I'm trying to calculate the RSI using the Poloniex API and PHP Trader EXtension. Here is what i have so far.
date_default_timezone_set( 'UTC' );
$api = new poloniex( 'xxxxxxx', 'xxxxx' );
$data = $api->getChartValues( 'BTC_LTC', strtotime( "-21 hours" ), time(), 300 );
print_r( $data);
$rsi = array();
foreach ( $data as $a )
{
$rsi[] = $a['close'];
}
$rsi = trader_rsi( array_reverse($rsi) , 14 );
The getChartValues calls the returnChartData API Function from Poloniex API.
After running the script, the output RSI is completely different than the valid one.
What i'm doing wrong?
maybe there is no need to reverse, here is my code that works fine
$rsi = array();
foreach ( $data as $a )
{
$rsi[] = $a['close'];
}
$rsi = trader_rsi( $rsi , 14 );
print_r( $rsi );
According to the RSI definition:
The relative strength index is calculated using the following formula:
RSI = 100 - 100 / (1 + RS)
Where RS = Average gain of up periods during the specified time frame / Average loss of down periods during the specified time frame/
[...]
The default time frame for comparing up periods to down periods is 14, as in 14 trading days.
Are you sure that the RS parameter in your computation is exactly the same than in "the valid one" ? And according to you what is "the valid one" source ?
Related
I'm trying to calculate the directional movement indicator for 5m interval using the API of Binance. I'm using 288 values of "High", "Open" and "Close" and
I'm calculating the True range and then the Average True Range (ATR) with a simple moving average of a window with 14 values. I'm using the same Simple Moving average technique
for the calculation of the +DI, -DI and the ADX, but the values that I get don't match the ones that are shown in trading view for the DMI. I have also tried using an
exponential moving average the ATR, the +Di and the -DI, but I still don't get matching values. I have also noticed that the DMI of Binance and Trading view do not match.
Do you know which smoothing techinique is used by the DMI of trading view?
$url = 'https://api.binance.com/api/v3/klines?symbol=BNBBTC&interval=5m&limit=288';
$candles = file_get_contents($url);
$candles = json_decode($candles, true);
$arr_results = array();
$high = array();
$low = array();
$close_arr = array();
$average = array();
for($i= 0; $i < sizeof($candles); $i++){
array_push($high, $candles[$i][2]);
array_push($low, $candles[$i][3]);
array_push($close_arr, $candles[$i][4]);
$av = ($candles[$i][2] + $candles[$i][3]) /2;
array_push($average, $av);
}
$plus_di = array_pop(trader_plus_di($high, $low, $close_arr, 14));
$minus_di = array_pop(trader_minus_di($high, $low, $close_arr, 14));
$adx = array_pop(trader_adx ($high, $low, $close_arr, 14));
To calculate the ATR, you need to smooth the TR (True Range) according to the following method :
Take a smoothing period nbCandles (nbCandles=14 candles typically), then:
First ATR value: ATR(1) = Sum{TR(1 -> nbCandles)} (i.e you sum the nbCandles first values of the TR to get your first value of the ATR) - If nbCandles = 14 then your first ATR value will be the sum of the first 14 values of TR.
Then, for the following ATR values, you use the following formula:
ATR(i) = ATR(i-1) - ATR(i-1)/nbCandles + TR(i)
Here is an example (based on 30 1 minutes candles historical record and 14 as the smoothing factor (number of candles used for smoothing)) :
Binance BTCUSDT 1m
I'm trying to read the calendar entries of rooms and output the next three events on their calendar. However I am testing first to see if I can get just the first 3 events of the day, but it seems the timezone or something else is causing it to not show events correctly.
This is a function I wrote:
function mb_get_meetings($mb_email = null, $mb_proxy = false, $mb_datetime_start = null, $mb_datetime_finish = null)
{
date_default_timezone_set('Australia/Melbourne');
// get the Microsoft Open Graph API
$mb_msgraph = json_decode(mb_microsoft_opengraph($mb_proxy), true); // custom function to get Beaker Token + $mb_proxy for internal proxy on or off for dev testing
$mb_msgraph_token = $mb_msgraph['access_token'];
$mb_datetimenow = new DateTime();
$mb_datetimezone = new DateTimeZone('Australia/Melbourne');
$mb_datetimenow->setTimezone($mb_datetimezone);
$mb_datetime_start = new DateTime($mb_datetime_start, $mb_datetimezone);
$mb_datetime_finish = new DateTime($mb_datetime_finish, $mb_datetimezone);
$mb_datetime_start = $mb_datetime_start->format('Y-m-d\TH:i:s.u');
$mb_datetime_finish = $mb_datetime_finish->format('Y-m-d\TH:i:s.u');
$mb_url_string = 'https://graph.microsoft.com/v1.0/users/' . $mb_email . '/calendar/calendarView?startDateTime=' . $mb_datetime_start . '&endDateTime=' . $mb_datetime_finish;
$mb_args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $mb_msgraph_token,
'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8',
'Prefer' => 'outlook.timezone="Australia/Melbourne"'
),
'httpversion' => '1.1'
);
$mb_output = wp_remote_get($mb_url_string, $mb_args);
$mb_output = wp_remote_retrieve_body($mb_output);
return $mb_output;
}
I am using Wordpress as the backend and it does retrieve the body.
In my frontend page I call:
$mbroom = (mb_get_meetings('email#domain.tld', true, 'today 7am', 'today 7pm'));
$mbroom = json_decode($mbroom, true);
$mbroom = $mbroom['value'];
foreach ($mbroom as $k => $v) {
// get the first 3 entries
if ($k < 3) {
print_r($k);
print_r($v['subject']);
print_r(date('g:i', strtotime($v['start']['dateTime']));
print_r(date('g:i', strtotime($v['end']['dateTime']));
print_r($v['organizer']['emailAddress']['name']);
echo '<hr>';
}
}
In the results, I will get sometimes no calendar entries while other times I might get entries for 2pm but not anything from 8am. I have tried changing it to hardcoded YYYY-MM-DDD 08:00 and YYYY-MM-DD 20:00 but to no avail. I have also tried yesterday and tomorrow but none/incorrect results.
I also tried booking an entire day with 30-minute meetings and that too wasn't working.
Am I doing something wrong?
I suggest sending the startDateTime and endDateTime parameters in UTC, formatted as ISO 8601 as described in the docs (https://learn.microsoft.com/en-us/graph/api/user-list-calendarview?view=graph-rest-1.0&tabs=http), which you have done. However, I'd suggest using a PHP constant, since it's less error-prone (https://www.php.net/manual/en/class.datetimeinterface.php#datetime.constants.iso8601). Doing something like the following for those parameters:
$startDateTime = new DateTime(date("Y-m-d H:i:s"));
$startDateTime = $startDateTime->format(DATE_ISO8601);
$startDateTime = substr($startDateTime, 0, strpos($startDateTime, '+'));
Edit:
Using substring to remove the locale part of the DateTime string was probably a naïve thing to do, but it does serve the purpose.
I have an array of digit time numbers (I get them from the input fields).
Here are a few examples:
00:00:10
00:03:00
01:20:00
My question is following, how do I check if a digit time is greater than another?
Following function works up to
00:01:00
After that I get an error.
$inputTimes = $request->input('times', []);
foreach ($inputTimes as $inputKey => $inputValue)
{
$Input = new Input();
$Input->input_start = $inputValue['input_start'];
$tInput = explode(':', $inputValue['input_timelapse']);
$implInput = implode('', $tInput);
$iImplInput = (int)$implInput;
// Check if time is greater
if($iImplInput > $iVideoDuration)
{
.. error time greater
}
}
I would convert it to Unix time by using the inbuild strtotime() function.
For example:
strtotime('01:20:00'); will output 1483492800 while strtotime('00:01:00'); will output 1483488060.
Hope this helped.
I am producing an rrd graph and I am facing 2 problems.
Problem 1: The numbers that I am printing they are integers without decimals, although when they are printed decimals appear. It is really confusing. So I looked online on the rrdgraph_graph and although that I am using the correct syntax and I am not applying any calculations I still do get floating values instead of integers.
According to the official website: %s place this after %le, %lf or %lg. This will be replaced by the appropriate SI magnitude unit and the value will be scaled accordingly (123456 -> 123.456 k).
I have attached a photo as sample of the output. I have also provide a working example code so if anyone understands the RRD's can view possible the error.
Problem 2: I was trying to add on my graph the VRULE:time#color[:legend][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]] function and based on the online instructions I can supply the time. Since my graph is shifting I was planning to do time (value) - 1800 sec. I wanted to place a vertical line in the middle of the graph so I could view approximately an average on 30 minutes values. When I am applying such a format I get this error:
<b>Graph error: </b>parameter '1400274668-1800' does not represent time in line VRULE:1400274668-1800#0000CD:Half way values
When I remove the subtraction everything work fine. Is there a way to produce this line in the middle of my graph?
<?php
$file = "snmp";
$rrdFile = dirname(__FILE__) . "/".$file.".rrd";
$in = "losses";
$png = "/home/linux/Desktop/";
$in_min = "vdef_in_min";
$in_max = "vdef_in_max";
$in_lst = "vdef_in_lst";
$in_av = "vdef_in_av";
$title = "Losses RRD::Graph";
$output = array("1h","1d");
$step = 5;
$heartbeat = 2 * $step;
while (1) {
sleep (1);
$options = array(
"--start","now -15s",
"--step", "".$step."",
"DS:".$in.":GAUGE:".$heartbeat.":0:U",
"RRA:LAST:0.5:1:3600",
"RRA:MIN:0.5:1:3600",
"RRA:MAX:0.5:1:3600",
"RRA:AVERAGE:0.5:6:600",
"RRA:LAST:0.5:300:288",
"RRA:MIN:0.5:300:288",
"RRA:MAX:0.5:300:288`",
"RRA:AVERAGE:0.5:600:144"
);
if ( !isset( $create ) ) {
$create = rrd_create(
"".$rrdFile."",
$options
);
if ( $create === FALSE ) {
echo "Creation error: ".rrd_error()."\n";
}
}
$t = time();
$losses = rand(0, 150);
$update = rrd_update(
"".$rrdFile."",
array(
"".$t.":".$losses.""
)
);
if ($update === FALSE) {
echo "Update error: ".rrd_error()."\n";
}
date_default_timezone_set('Europe/Stockholm');
$timezone = new DateTime(NULL, new DateTimeZone('Europe/Stockholm'));
$date = date('l jS \of F Y h\\:i\\:s A' , $timezone->format('U'));
$comment = "RRD last updated:".$date;
$comment = str_replace( ":", "\\:", $comment );
$graph = "Graph last updated:".$date;
$graph = str_replace( ":", "\\:", $graph );
foreach ($output as $test) {
$final = array(
"--start","end - ".$test."",
"--end", "".$t."",
"--title=".$file." RRD::Graph with - ".$test." Periods",
"--vertical-label=Bytes(s)/sec",
"--right-axis-label=latency(ms)",
"--alt-y-grid", "--rigid",
"--width", "800", "--height", "500",
"--lower-limit=0",
"--no-gridfit",
"--slope-mode",
"DEF:".$in."_def=".$file.".rrd:".$in.":LAST",
"CDEF:inbytes=".$in."_def",
"VDEF:".$in_lst."=inbytes,LAST",
"VDEF:".$in_min."=inbytes,MINIMUM",
"VDEF:".$in_max."=inbytes,MAXIMUM",
"VDEF:".$in_av."=inbytes,AVERAGE",
"COMMENT:\\n",
"LINE2:".$in."_def#FF0000:".$in."",
"GPRINT:".$in_min.": Minimum\:%6.2lf %S",
"GPRINT:".$in_max.":Maximum\:%6.2lf %S",
"GPRINT:".$in_lst.":Last\:%6.2lf %s",
"GPRINT:".$in_av.":Average\:%6.2lf %s",
"COMMENT:\\n",
"VRULE:".$t."#0000CD:Half way values",
"COMMENT:\\n",
"HRULE:50#FFFF00:Maximum value",
"COMMENT:\\n",
"COMMENT: ",
"COMMENT:\\n",
"COMMENT:".$comment."\\r",
"COMMENT:".$graph."\\r"
);
$outputPngFile = rrd_graph(
"".$png."".$test.".png",
$final
);
if ($outputPngFile === FALSE) {
echo "<b>Graph error: </b>".rrd_error()."\n";
}
}
$debug = rrd_lastupdate (
"".$rrdFile.""
);
if ($debug === FALSE) {
echo "<b>Graph result error: </b>".rrd_error()."\n";
}
var_dump ($debug);
}
?>
The answer to your first problem is almost certainly Data Normalisation. Since you are not updating the RRD precisely on the Step boundary every time, the submitted data values are normalised to a step boundary, resulting in the decimal values. To understand this, read Alex van den Bogeardt's excellent article on the subject.
Your second problem is that you simply cannot use the VRULE declaration in that way. The first parameter to VRULE may be either a number or a VDEF variable, but it cannot be a formula. Therefore, VRULE:12345678#0000CD:Foo is fine, as is VRULE:vdefname#FF00FF:Bar. However you may not use VRULE:123456-123#0000CD:No. Do the calculation before, like this:
"VRULE:".($t-1800)."#0000CD:Half way values",
... and this should result in a valid syntax.
Not sure if this is possible with just php or if I'd need something else too. Basically I'd like to have an array with a bunch of entries, such as:
(1234,5432,5678,5899,3245)
And I'd like to have the php randomly select one entry from the array AND stick to that entry it selected for 3 days. So for example, on a given date, it would pull "5432" from the array, then it would hold that entry for 3 days, then after 3 days it would pick another entry and hold it for 3 days, etc.
Any ideas how this could be done? Can it be done with just php? Thanks so much for any help.
Assuming you're running a PHP program (command line), and not running a script on a web server you can run this script to stay on all the time and wait to draw.
$entries = array( 34534, 435, 345 );
while(1) {
// subtract 1 from total number of entries because arrays start at an index of 0.
$totalNumberOfEntries = sizeof( $entries ) - 1;
// if no entries left, quit the program
if ($totalNumberOfEntries <= 0) break;
// grab a random index from your array using `mt_rand()` function
$entry = $entries[ mt_rand(0, $totalNumberOfEntries - 1) ];
// write the entry to a file
file_put_contents( 'entry.txt', $entry, FILE_APPEND );
// wait 3 days to draw again
sleep( 3600 * 24 * 3 );
}