Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate percentage change in stock price instead of raw stock price #26

Merged
merged 18 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 50 additions & 21 deletions random_price.cpp
Original file line number Diff line number Diff line change
@@ -1,44 +1,73 @@
// code related to randomness
#include "events.h"
#include "random_price.h"
#include "stock.h"
#include <cstdlib>
#include <iostream>
#include <list>
#include <map>
#include <random>
#include <string>
#include <vector>

double init_stock_price(int price_profile) {
float init_stock_price(int price_profile) {
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<double> distribution(5.0, 2.0);
std::normal_distribution<float> distribution(5.0, 2.0);
if (price_profile == 2) {
distribution.param(std::normal_distribution<double>::param_type(50.0, 20.0));
distribution.param(std::normal_distribution<float>::param_type(50.0, 20.0));
}
if (price_profile == 3) {
distribution.param(std::normal_distribution<double>::param_type(150.0, 50.0));
distribution.param(
std::normal_distribution<float>::param_type(150.0, 50.0));
}
return distribution(gen);
return abs(distribution(gen));
}
double random_sd(float price) {

float init_sd() {
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<double> d(0.03 * price, 0.02 * price);
return abs(d(gen));
std::normal_distribution<float> distribution(0.5, 0.5);
return abs(distribution(gen));
}
double random_stock(float & mean, float & sd, float & upper_limit,
float & lower_limit) {

float percentage_change_price(Stock & stock) {
float current_price = stock.return_most_recent_history(1)[0];
float init_price = stock.return_most_recent_history(99999999)[0];
float offset = stock.get_attribute(mean) + stock.sum_attribute(mean);
float sd = stock.get_attribute(standard_deviation) + stock.sum_attribute(standard_deviation);
unsigned int rounds_passed = stock.get_history_size();
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<double> distribution(mean, sd);
float price = distribution(gen);
// for mean > temp i.e. falling prices
if ((mean - price) > (lower_limit * mean)) {
mean = price;
if (current_price < init_price / 10) {
stock.change_mean(current_price * 0.3);
}
float temp = 100 * abs(init_price - current_price) / init_price;
float upper_limit = 50 + (rounds_passed * rounds_passed) / 15 + temp;
float lower_limit = -1 * (50 + rounds_passed + temp);
float z_score_upper_limit = (upper_limit - offset) / sd;
float z_score_lower_limit = (lower_limit - offset) / sd;
for (int i = 0; i < 5; i++) {
if (z_score_lower_limit > 1.3) {
stock.change_mean(current_price * 0.3);
}
if (z_score_upper_limit < -1.3) {
stock.change_mean(current_price * -0.3);
}
}
// rising prices
if ((price - mean) > (upper_limit * mean)) {
mean = price;
std::normal_distribution<float> distribution(offset, sd);

if (lower_limit < -100) {
lower_limit = -100;
}
float x;
while (true) {
float x = distribution(gen);
if (x < upper_limit and x > lower_limit) {
return x;
}
}
sd = random_sd(price);
return price;
}

unsigned int random_integer(unsigned int max_integer) {
return rand() % max_integer;
}
32 changes: 20 additions & 12 deletions random_price.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,34 @@
#ifndef
#define are to prevent double include the header
*/
#include "stock.h"

/**
* Initial Stock Price Generator
* if price_profile=2 mean 50 sd 20; if price_profile=3 mean 150 sd 50; else mean 5 sd 2;
*Stock prices cluster in 3 tiers in our world: about 5 hkd (a=ELSE) variating about 2 hkd; , 50 hkd(a=2) variating about 20 hkd,
*and 150 hkd(a=3)variating about 50 hkd (based on a very little sample observation of real world).
* - if a=1 mean 5 s.d. 2;
* - if a=2 mean 50 s.d. 20;
* - if a=3 mean 150 s.d. 50;
*/
double init_stock_price(int a);
float init_stock_price(int a);
// there is ABSOLUTELY nothing at line 15
/**
* Stock Standard Deviation Generator (for both initial and after initial)
* s.d. usually 1%-5% of initial stock price;
* modelling with absolute value of norm dist mean 0.03*init_price; s.d. 0.02*init_price (yes, s.d. of s.d.)
* Initiaises a reasonable standard deviation; first around 0.5, second around 3, third around 10
*/
double random_sd(float init_price);
float init_sd(int price_profile);

/**
* Random Stock Price Generator (non-initialising)
* requires mean, s.d., upper limit increase threshold (FRACTION of mean) and lower limit decrease threshold (FRACTION of mean)
* e.g. both 0.03; then the mean changes to exactly the new price if the value differ from mean by 3%
* There is a upper limit and lower limit that the realisation of the % change must fall between.
* - All data is taken from a stock class.
* As each round pass we allow for more and more chaotic behaviour by making the bounds less tight.
* - where n is number of rounds
* - The rate this happens is n^2/15 for upper bound
* - and n for lower bound before lower bound reach -100
* - just for fun (chaotic evil smirk). Upon devastating events which leads to
* a stock price only 10 % left of it's initial, we increase mean to prevent a game over.
* Upon we are 90.32% sure the bounds would be wrong we bump the mean.
*/
double random_stock(float & mean, float & sd, float & upper_limit, float & lower_limit);
float percentage_change_price(Stock & stock);

/**
* Random integer function in choosing stock type
* Return a random integer from 0 to max - 1
Expand Down