im creating an multiplication table system in PHP.
The input tho this system is an table number and the amount of questions.
The table 1 is skipped so 2 to input table
At this point I just fill an array like this:
$nCount = $_POST['count'];
$nHighest = $_POST['table'];
$aSums = [];
$nCounter = 0;
while($nCount > 0){
$cSumString = rand(2, $nHighest) . "*" . rand(1, 10);
$aSums[$nCounter] = $cSumString
$nCount--;
$nCounter++;
}
I want to parse the questions in multiple ways:
3 * 5 = ... (normal)
... * 5 = 25 (first number to fill in)
8 * ... = 16 (second to fill in)
This needs to be randomised.
Example:
1 * 2 = ...
6 * ... = 12
... * 4 = 20
8 * 4 = ...
2 * ... = 6
The only thing I know that should be able to so this is a switch but I cant seem to get it to work propperly so if anyone can give me a push in the right direction i would appreciate it. Im not asking for instacode just some tips would be great.
$nCount = $_POST['count'];
$nHighest = $_POST['table'];
$aSums = [];
$leftOut = ['leftFactor', 'rightFactor', 'product'];
for ($i = 0; $i <= $nCount; $i++) {
$leftOutRand = rand(0, count($leftOut) - 1);
$factor = rand(1, $nHighest);
$product = rand(0, $nHighest) * $factor;
switch($leftOut[$leftOutRand]) {
case 'leftFactor':
$cSumString = '...' . ' * ' . $factor . ' = ' . $product;
break;
case 'rightFactor':
$cSumString = $factor . ' * ' . '...' . ' = ' . $product;
break;
case 'product':
$cSumString = rand(1, $nHighest) . ' * ' . rand(1, $nHighest) . ' = ' . '...';
break;
}
$aSums[$i] = $cSumString;
}
example Output:
2 * ... = 4
... * 2 = 6
1 * 1 = ...
... * 2 = 6
3 * ... = 12
2 * ... = 2
2 * 4 = ...
4 * ... = 0
3 * 1 = ...
2 * 1 = ...
... * 4 = 16
1 * ... = 2
... * 2 = 2
1 * 4 = ...
3 * ... = 9
2 * 3 = ...
2 * ... = 6
... * 1 = 3
... * 4 = 4
1 * 1 = ...
... * 3 = 9
<?php
$total = 4;
$table = 7;
$generate_pair = function() use ($table)
{
$first = rand(1, 10);
$last = rand(2, $table);
return [$first, $last];
};
$pairs = [];
while (count($pairs) < $total) {
$pair = $generate_pair();
if(!in_array($pair, $pairs))
$pairs[] = $pair;
}
$questions = array_map(function ($v) {
return sprintf('%d * %d', $v[0], $v[1]);
}, $pairs);
var_dump($questions);
Example output:
array(4) {
[0]=>
string(5) "7 * 3"
[1]=>
string(5) "5 * 7"
[2]=>
string(5) "5 * 2"
[3]=>
string(5) "6 * 2"
}
I would personally put it in an array and read it from there then its easier to get it trough an switch like Mark labenski mentioned and I would do it like this:
$questpertable = floor($questions / ($table-1));
$nTableCounter = 2;
$array = [];
for ($nX = 0; $nX < ($table-1); $nX++){
for ($nY = 0; $nY < $questpertable;){
$left = rand(1, 10);
$right = $tablecounter;
$answer = $left * $right;
$array[$nY] = array($left, $right, $answer );
$Y++;
}
$tablecounter++;
}
The only thing that misses here is the residual value u will have to find something to fix this.
Related
I got a set of different events, all with their own odds to happen. Is there a way to calculate the odds for them combined, so that I get a the odds for 0, 1 2 and so on to happen.
The math is easy, but the number of calculations grow quick, so I was hoping there was a function that could help me.
Example with three factors :
Event | Yes | No
A | 3% | 97%
B | 4% | 96%
C | 5% | 95%
0 Happening : $A[no] * $ B[no] * $c[no]
1 happening : $A[yes] * $ B[no] * $c[no] + $A[no] * $ B[yes] * $c[no] + $A[no] * $ B[no] * $c[yes]
2 happening = $A[yes] * $ B[yes] * $c[no] + $A[yes] * $ B[no] * $c[yes] + $A[no] * $ B[yes] * $c[yes]
3 happening : $A[yes] * $ B[yes] * $c[yes]
This is easy to write in php, my problem is how this scale up if i add more events. Just adding one more doubles the number of caclulations, and soon the code would be really long.
So is there an easier way to do this? I'll be grateful for any tips or ideas.
This is quite slow implementation.
Let's consider a case with 5 events.
Odds of 0 events happening is:
$no[0] * $no[1] * $no[2] * $no[3] * $no[4]
Odds of 1 event happening is:
$no[0] * $no[1] * $no[2] * $no[3] * $yes[4] +
$no[0] * $no[1] * $no[2] * $yes[3] * $no[4] +
$no[0] * $no[1] * $yes[2] * $no[3] * $no[4] +
...
where you go through all multiplications where there is exactly 1 'yes' choice.
Odds of 2 events happening is:
$no[0] * $no[1] * $no[2] * $yes[3] * $yes[4] +
$no[0] * $no[1] * $yes[2] * $no[3] * $yes[4] +
$no[0] * $no[1] * $yes[2] * $yes[3] * $no[4] +
...
where you go through all multiplications where there is exactly 2 'yes' choices.
This can be generalized: To calculate odds of N events happening you go through all multiplications where there is exactly N 'yes' choices.
Now when you need to calculate all odds from 0 to 5 events happening, you need to go through all possible combinations of yes/no choices and add each multiplication to $odds[$yesCount].
$no[0] * $no[1] * $no[2] * $no[3] * $no[4] ; added to $odds[0]
$no[0] * $no[1] * $no[2] * $no[3] * $yes[4] ; added to $odds[1]
$no[0] * $no[1] * $no[2] * $yes[3] * $no[4] ; added to $odds[1]
$no[0] * $no[1] * $no[2] * $yes[3] * $yes[4] ; added to $odds[2]
$no[0] * $no[1] * $yes[2] * $no[3] * $no[4] ; added to $odds[1]
...
$yes[0] * $yes[1] * $yes[2] * $yes[3] * $yes[4] ; added to $odds[5]
There are total of 2**5 = 32 different multiplications here, or generally 2**$eventCount.
It is easy to go through all these cases if we assign a number to each case from 0 to 2**$eventCount-1, and then use bits of this number to select whether 'yes' or 'no' choice of each event is included in multiplication, and finally add each multiplication result to $odds[$yesCount]:
// number of events
$eventCount = 5;
// odds of each event happening
$yes = [ 0.10, 0.50, 0.32, 0.66, 0.99 ];
// odds of each event not happening
$no = [];
for ($eventNumber = 0; $eventNumber < $eventCount; $eventNumber++) {
$no[$eventNumber] = 1 - $yes[$eventNumber];
}
// initialize combined $odds to zero
$odds = [];
for ($n = 0; $n <= $eventCount; $n++) {
$odds[$n] = 0;
}
// calculate combined odds
for ($case = 0; $case < 2 ** $eventCount; $case++) {
$multiplication = 1;
$yesCount = 0;
for ($eventNumber = 0; $eventNumber < $eventCount; $eventNumber++) {
if ($case & (1 << $eventNumber)) {
$yesCount++;
$multiplication *= $yes[$eventNumber];
} else {
$multiplication *= $no[$eventNumber];
}
}
$odds[$yesCount] += $multiplication;
}
// show combined odds
for ($n = 0; $n <= $eventCount; $n++) {
echo "Odds of " . $n . " events happening is " . $odds[$n] . "<br>\n";
}
Let's see what we actually need here. Let's assume, we have an array of chances:
$chances = [0.8, 0.3, 0.15];
What we need is to get those results with the following calculations:
// 0.119
$chance0 = (1-$array[0]) * (1-$array[1]) * (1-$array[2]);
// 0.548
$chance1 = $array[0] * (1-$array[1]) * (1-$array[2]) + (1-$array[0]) * $array[1] * (1-$array[2]) + (1-$array[0]) * (1-$array[1]) * $array[2];
// 0.297
$chance2 = $array[0] * $array[1] * (1-$array[2]) + $array[0] * (1-$array[1]) * $array[2] + (1-$array[0]) * $array[1] * $array[2];
// 0.036
$chance3 = $array[0] * $array[1] * $array[2];
What we actually need, is based on an integer that represents a number of successful chances, get every non-repeating combination from a pool of numbers, and make the rest "inversive", i.e. make them (1 - chance)
To achieve that, I used this answer and modified the code a bit. From the mentioned answer, we get non-repeating combinations of chances (meaning, that in case we get 2 successful chances, 0.8 and 0.15 are same as 0.15 and 0.8). Next, we use an array_diff to see what is left and assume those are failing chances. But since those are failing chances, we need to "reverse" them, calling array_map with the respective callback. The last thing is to calculate array_product to get the chance of the event happening.
And finally we just array_sum all the chances.
class Combinations implements Iterator
{
protected $c = null;
protected $s = null;
protected $n = 0;
protected $k = 0;
protected $pos = 0;
function __construct($s, $k) {
if(is_array($s)) {
$this->s = array_values($s);
$this->n = count($this->s);
} else {
$this->s = (string) $s;
$this->n = strlen($this->s);
}
$this->k = $k;
$this->rewind();
}
function key() {
return $this->pos;
}
function current() {
$r = array();
for($i = 0; $i < $this->k; $i++)
$r[] = $this->s[$this->c[$i]];
return is_array($this->s) ? $r : implode('', $r);
}
function next() {
if($this->_next())
$this->pos++;
else
$this->pos = -1;
}
function rewind() {
$this->c = range(0, $this->k);
$this->pos = 0;
}
function valid() {
return $this->pos >= 0;
}
protected function _next() {
$i = $this->k - 1;
while ($i >= 0 && $this->c[$i] == $this->n - $this->k + $i)
$i--;
if($i < 0)
return false;
$this->c[$i]++;
while($i++ < $this->k - 1)
$this->c[$i] = $this->c[$i - 1] + 1;
return true;
}
}
function getTotalChances($calculateFrom, $successCount)
{
$totalChance = [];
foreach(new Combinations($calculateFrom, $successCount) as $success)
{
$failure = array_map(function($element) {
return (1-$element);
}, array_diff($calculateFrom, $success));
$chance = array_product(array_merge($success, $failure));
$totalChance[] = $chance;
}
return(array_sum($totalChance));
}
$calculateFrom = [0.8, 0.3, 0.15];
var_dump(getTotalChances($calculateFrom, 2));
Now if you run the following, you will get what you need:
var_dump(getTotalChances($calculateFrom, 0)); // 0.119
var_dump(getTotalChances($calculateFrom, 1)); // 0.548
var_dump(getTotalChances($calculateFrom, 2)); // 0.297
var_dump(getTotalChances($calculateFrom, 3)); // 0.036
Ok, I don't even know where to start with this one! I'll try and explain what I want to achieve, and we'll go from there....
I have a list of dates each with an associated number, say from 20-100. What I want to do is to output the date in a shade which represents the associated number. So 20 would display in a light blue and 100 in a dark blue. My code so far looks like this...
dateArray = Array('2001-01-01'=>30, '2001-02-01'=>40, '2001-03-01'=>50, '2001-04-01'=>60, '2001-05-01'=>70, '2001-06-01'=>80, '2001-07-01'=>90, '2001-08-01'=>90, '2001-09-01'=>80, '2001-10-01'=>70, '2001-11-01'=>60, '2001-12-01'=>50)
$maxNum = max($dateArray);
$minNum = min($dateArray);
foreach($dateArray AS $date => $num){
$lightest = 'rgb(204,204,255)';
$darkest = 'rgb(0, 0, 179)';
///magic that converts $num into $shade goes here///
echo "<span style='color:$shade'>$date</span><br>"
}
Any ideas? Thanks
I would do something like that :
$dateArray = Array('2001-01-01'=>30, '2001-02-01'=>40, '2001-03-01'=>50, '2001-04-01'=>60, '2001-05-01'=>70, '2001-06-01'=>80, '2001-07-01'=>90, '2001-08-01'=>90, '2001-09-01'=>80, '2001-10-01'=>70, '2001-11-01'=>60, '2001-12-01'=>50)
// get max and min values
$maxNum = max($dateArray);
$minNum = min($dateArray);
// set rgb values for max and min
$lightest = array(204, 204, 255);
$darkest = array(0, 0, 179);
foreach($dateArray AS $date => $num)
{
// get a "delta" where the current num value is
$delta = ($num / $maxNum) - $minNum;
// get a pro-rata values thanks to $delta
$shadesNum = array(
$delta * ($lightest[0] - $darkest[0]) + $darkest[0],
$delta * ($lightest[1] - $darkest[1]) + $darkest[1],
$delta * ($lightest[2] - $darkest[2]) + $darkest[2]
);
echo "<span style='rgb(".implode(',', $shadesNum).")'>$date</span><br>";
}
Some languages have a "lerp" function - linear interpolation. Quite useful.
My suggestion:
for ($x1=20; $x1<=100; $x1+=10)
echo $x1 . ": " . getshade($x1) . "<br />\n";
function getshade($num) {
$rlight = 204;
$glight = 204;
$blight = 255;
$rdark = 0;
$gdark = 0;
$bdark = 179;
$lightnum = 20;
$darknum = 100;
$k01 = ($num-$lightnum)/($darknum-$lightnum); // 0 to 1
$rshade = ilerp($rlight, $rdark, $k01);
$gshade = ilerp($glight, $gdark, $k01);
$bshade = ilerp($blight, $bdark, $k01);
return "rgb($rshade,$gshade,$bshade)"; }
function lerp($start, $end, $k01) { // linear interpolation
return $k01*$end + (1.0-$k01)*$start; }
function ilerp($start, $end, $k01) { // integer lerp
return intval($k01*$end + (1.0-$k01)*$start); }
EDIT: Same thing but better:
$rgblight = [204,204,255];
$rgbdark = [0,0,179];
$numlight = 20;
$numdark = 100;
for ($x1=20; $x1<=100; $x1+=10)
echo $x1 . ": " . getshade2($x1, $numlight, $numdark, $rgblight, $rgbdark) . "<br />\n";
function getshade2($num, $numlight, $numdark, $rgblight, $rgbdark) {
$k01 = ($num-$numlight)/($numdark-$numlight);
for ($i1=0; $i1<3; $i1+=1)
$rgb[$i1] = ilerp($rgblight[$i1], $rgbdark[$i1], $k01);
return "rgb({$rgb[0]},{$rgb[1]},{$rgb[2]})"; }
I have an array year_values containing some values like
$year_values = array();
foreach($year_strings as $str) {
$year_values[] = explode(",", $str);
}
then I apply a query for extracting some values from database
$sql = "SELECT inventory.holdingcost as holdingcost,
inventory.ordercost as ordercost, inventory.unitprice as unitprice,
inventory.lead_time as lead_time, items.id as iid
FROM inventory, items
WHERE inventory.item_name = items.item_name";
mysql_error();
$result = mysql_query($sql);
foreach($year_values as $vals) {
while ($row = mysql_fetch_row($result)) {
$w = $row[2];
$e = $row[0];
$r = $row[1];
$tt = $row[3];
$eo = sqrt(2 * $vals[5] * $r / ($e * $w));
$eoq = round($eo, 1);
$ro = $vals[5] / 360;
$rop = round($ro * $tt);
$op = round($vals[5] / $eoq, 1);
$cc = round(89 / $op);
$h = round((($eoq * $e * $w) / 2), 2);
$o = round((($r * $vals[5]) / $eoq), 2);
$z = round($h + $o, 2);
}
}
When I use foreach above while loop it just takes first value of $year_values as $vals[5], I want to make computations inside while for every value of array $year_values.
How to correct it?
repetition is occurring in value1 i.e $val[5] currently:
Value1 Value 2 Value 3
199 202 0.25
199 205 0.25
199 210 0.25
199 230 0.25
1698 202 0.25
1698 205 0.25
1698 210 0.25
1698 230 0.25
instead i want the values to be displayed like
Value1 Value 2 Value 3
199 202 0.25
1698 205 0.25
15 210 0.25
971 230 0.25
I guess you just have to store all your data, so you could reuse it.
$result = mysql_query($sql);
$rows = array() ;
while ($row = mysql_fetch_row($result)){
$rows[] = $row ;
}
foreach($year_values as $vals) {
foreach($rows as $row){
$w = $row[2];
$e = $row[0];
$r = $row[1];
$tt = $row[3];
$eo = sqrt(2 * $vals[5] * $r / ($e * $w));
$eoq = round($eo, 1);
$ro = $vals[5] / 360;
$rop = round($ro * $tt);
$op = round($vals[5] / $eoq, 1);
$cc = round(89 / $op);
$h = round((($eoq * $e * $w) / 2), 2);
$o = round((($r * $vals[5]) / $eoq), 2);
$z = round($h + $o, 2);
}
}
Simply reverse the statements:
while ($row = mysql_fetch_row($result)) {
foreach($year_values as $vals) {
$w = $row[2];
$e = $row[0];
$r = $row[1];
$tt = $row[3];
$eo = sqrt(2 * $vals[5] * $r / ($e * $w));
$eoq = round($eo, 1);
$ro = $vals[5] / 360;
$rop = round($ro * $tt);
$op = round($vals[5] / $eoq, 1);
$cc = round(89 / $op);
$h = round((($eoq * $e * $w) / 2), 2);
$o = round((($r * $vals[5]) / $eoq), 2);
$z = round($h + $o, 2);
}
}
mysql_fetch_row will return false once the rows have been fetched all. To reuse it you should store them in a variable (like the response made by Jari) or you could switch the two cycles (see imulsion's answer)
Holt-Winters is introduced here:
http://en.wikipedia.org/wiki/Holt-Winters
The Seasonal Dampened version of it is discussed here (scroll down the page):
http://otexts.com/fpp/7/5/
In a nutshell, it basically looks at 3 things:
long-term trend
short-term trend
seasonal trend
It also doesn't average those together, because really what you need is weighted averaging, where seasonal and short-term are more significant than long-term trend, naturally, with financial data trends.
Given $anYear1 and $anYear2, how do I apply the Holt-Winters Seasonal Dampened Method to forecast 2 more months past the end of $anYear2? Assume $anYear1 is an array of 12 numbers. Assume $anYear2 is an array of a range of 0 to 12 numbers.
So, I can fill it with random data like so:
<?php
$anYear1 = array();
$anYear2 = array();
$nStop = 10; // so we need 11 and 12 of the year
for ($i = 1; $i <= 12; $i++) {
$anYear1[$i] = rand(200,500);
if ($i <= $nStop) {
// give it a natural lift like real financial data
$anYear2[$i] = rand(400,700);
}
}
$nSeasonRange = 4; // 4 months in a business quarter
Therefore, I want to create a function like so:
function forecastHoltWinters($anYear1, $anYear2, $nSeasonRange = 4) {
///////////////////
// DO MAGIC HERE //
///////////////////
// an array with 2 numbers, indicating 2 months forward from end of $anYear2
return $anForecast;
}
$anForecast = forecastHoltWinters($anYear1, $anYear2, $nSeasonRange);
echo "YEAR 1\n";
print_r($anYear1);
echo "\n\nYEAR 2\n"
print_r($anYear2);
echo "\n\nTWO MONTHS FORECAST\n";
print_r($anForecast);
Note: I have found a Github example here, but it doesn't show how to do a projection. It is also discussed here.
I found a way to adapt Ian Barber's function to do what I needed.
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
$anYear1 = array();
$anYear2 = array();
$nStop = 10;
for($i = 1; $i <= 12; $i++) {
$anYear1[$i] = rand(100,400);
if ($i <= $nStop) {
$anYear2[$i+12] = rand(200,600);
}
}
print_r($anYear1);
print_r($anYear2);
$anData = array_merge($anYear1,$anYear2);
print_r(forecastHoltWinters($anData));
function forecastHoltWinters($anData, $nForecast = 2, $nSeasonLength = 4, $nAlpha = 0.2, $nBeta = 0.01, $nGamma = 0.01, $nDevGamma = 0.1) {
// Calculate an initial trend level
$nTrend1 = 0;
for($i = 0; $i < $nSeasonLength; $i++) {
$nTrend1 += $anData[$i];
}
$nTrend1 /= $nSeasonLength;
$nTrend2 = 0;
for($i = $nSeasonLength; $i < 2*$nSeasonLength; $i++) {
$nTrend2 += $anData[$i];
}
$nTrend2 /= $nSeasonLength;
$nInitialTrend = ($nTrend2 - $nTrend1) / $nSeasonLength;
// Take the first value as the initial level
$nInitialLevel = $anData[0];
// Build index
$anIndex = array();
foreach($anData as $nKey => $nVal) {
$anIndex[$nKey] = $nVal / ($nInitialLevel + ($nKey + 1) * $nInitialTrend);
}
// Build season buffer
$anSeason = array_fill(0, count($anData), 0);
for($i = 0; $i < $nSeasonLength; $i++) {
$anSeason[$i] = ($anIndex[$i] + $anIndex[$i+$nSeasonLength]) / 2;
}
// Normalise season
$nSeasonFactor = $nSeasonLength / array_sum($anSeason);
foreach($anSeason as $nKey => $nVal) {
$anSeason[$nKey] *= $nSeasonFactor;
}
$anHoltWinters = array();
$anDeviations = array();
$nAlphaLevel = $nInitialLevel;
$nBetaTrend = $nInitialTrend;
foreach($anData as $nKey => $nVal) {
$nTempLevel = $nAlphaLevel;
$nTempTrend = $nBetaTrend;
$nAlphaLevel = $nAlpha * $nVal / $anSeason[$nKey] + (1.0 - $nAlpha) * ($nTempLevel + $nTempTrend);
$nBetaTrend = $nBeta * ($nAlphaLevel - $nTempLevel) + ( 1.0 - $nBeta ) * $nTempTrend;
$anSeason[$nKey + $nSeasonLength] = $nGamma * $nVal / $nAlphaLevel + (1.0 - $nGamma) * $anSeason[$nKey];
$anHoltWinters[$nKey] = ($nAlphaLevel + $nBetaTrend * ($nKey + 1)) * $anSeason[$nKey];
$anDeviations[$nKey] = $nDevGamma * abs($nVal - $anHoltWinters[$nKey]) + (1-$nDevGamma)
* (isset($anDeviations[$nKey - $nSeasonLength]) ? $anDeviations[$nKey - $nSeasonLength] : 0);
}
$anForecast = array();
$nLast = end($anData);
for($i = 1; $i <= $nForecast; $i++) {
$nComputed = round($nAlphaLevel + $nBetaTrend * $anSeason[$nKey + $i]);
if ($nComputed < 0) { // wildly off due to outliers
$nComputed = $nLast;
}
$anForecast[] = $nComputed;
}
return $anForecast;
}
I am trying to get the accumulative swing index for an aapl stock chart. I am using this calculation for reference.
http://www.barchart.com/education/std_studies.php?what=int_swing&hideheader=true#study
This is what I have written so far. This should return 252.09 but I cannot get it to work.
$asi[0] = -78.75
$ht = 584; // High today
$lt = 574.25; // low
$ct = 584.00; // close
$ot = 578; // open
$hy = 574; // High yesterday
$ly = 565.61;
$cy = 569.05;
$oy = 571.67;
$k = max(($hy-$ct),($ly-$ct));
$abc = array(($ht-$cy), ($lt-$cy), ($ht-$lt));
$max = max($abc);
$r = 0;
if($max == $abc[0]){
$r = ($ht-$cy)-.5*($lt-$cy)+.25*($cy-$oy);
}elseif($max == $abc[1]){
$r = ($lt-$cy)-.5*($ht-$cy)+.25*($cy-$oy);
}elseif($max == $abc[2]){
$r = ($ht-$lt)+.25*($cy-$oy);
}else{
echo "Error in welles accumulative swing index";
exit;
}
$l = 3 //period;
$val = 50 * (($cy - $ct) + .5 *($cy - $oy) + .25*($ct-$ot)) / $r * $k / $l;
$asi[] = $asi[$i-1] + $val;
Any help would be greatly appreciated.
I have tried to implement this index newly symbol-by-symbol and have get different result (swing: -248.7032967033 ).
May be your control value wrong?
That is my code:
class Swing
{
public function calculate($high_price, $low_price, $close_price, $open_price, $t)
{
// (Ct-1 - Ct)
$summand0 = ($close_price[$t-1] - $close_price[$t]);
// 0.5(Ct-1 - Ot-1)
$summand1 = 0.5 * ($close_price[$t-1] - $open_price[$t-1]);
// 0.25(Ct - Ot)
$summand2 = 0.25 * ($close_price[$t] - $open_price[$t]);
$limit_move_default = 3.0;
$r = $this->get_r_value($high_price, $low_price, $close_price, $open_price, $t);
$k = $this->get_k_value($high_price, $low_price, $close_price, $t);
$factor0 = 50.0 * ($summand0 + $summand1 + $summand2) / $r;
$factor1 = $k / $limit_move_default;
// SWING = 50 * ((Ct-1 - Ct)+ 0.5(Ct-1 - Ot-1)+ 0.25(Ct - Ot))/ R * K / M
return $factor0 * $factor1;
}
public function get_k_value($high_price, $low_price, $close_price, $t)
{
// K= MAX(| Ht-Ct-1|, | Lt-Ct-1|)
return max(
abs($high_price[$t] - $close_price[$t-1]),
abs($low_price[$t] - $close_price[$t-1]));
}
public function get_r_value($high_price, $low_price, $close_price, $open_price, $t)
{
// A. |Ht-Ct-1|
$a = abs($high_price[$t] - $close_price[$t-1]);
// B. |Lt-Ct-1|
$b = abs($low_price[$t] - $close_price[$t-1]);
// C. |Ht-Lt|
$c = abs($high_price[$t] - $low_price[$t]);
$max_value = max($a, $b, $c);
$d = abs($high_price[$t] - $low_price[$t]);
if($a == $max_value)
// R= (| Ht-Ct-1|)-.5(| Lt-Ct-1|)+.25(| Ct-1-Ot-1|)
return $a - 0.5 * $b + 0.25 * $d;
if($b == $max_value)
// R= (| Lt-Ct-1|)-.5(| Ht-Ct-1|)+.25(| Ct-1-Ot-1|)
return $b - 0.5 * $a + 0.25 * $d;
if($c == $max_value)
// R= (| Ht-Lt|)+.25(| Ct-1-Ot-1|)
return $c + 0.25 * $d;
}
};
$swing = new Swing();
$high_price = array(574.0, 584.0);
$low_price = array(565.61, 574.25);
$close_price = array(569.05, 584.0);
$open_price = array(571.67, 578.0);
$value = $swing->calculate($high_price, $low_price, $close_price, $open_price, 1);
echo("swing: $value \n");
$d looks wrong.
It should be abs($close_price[$t-1] - $open_price[$t-1]);