The State Capitalist
Friday, October 11, 2024
Saturday, October 5, 2024
grse optimization to find BRs
To optimize the buy and sell conditions to create a smoother equity curve, we can employ several techniques. One possible approach is to tune the breakout and breakdown conditions using optimization methods such as grid search, genetic algorithms, or optimization libraries. We'll explore how to adjust the conditions for a better risk-adjusted return, such as:
- Varying the breakout threshold (currently set at 3%).
- Modifying the closing percentage range in the upper 30%.
- Adjusting the breakdown threshold (currently set at -3%).
Approach:
- Optimization setup: We can use an optimization library such as
DEoptim
(Differential Evolution), or a simple grid search to optimize the thresholds. - Objective: Minimize the standard deviation (volatility) of the equity curve while maximizing the total returns. This will smooth the equity curve.
- Optimization of buy/sell conditions: Tune the breakout threshold (currently 3%) and breakdown threshold (currently -3%) to achieve a better trade-off between return and risk.
Optimization using
DEoptim
:- We define a function
trading_strategy()
that calculates the return and volatility of the strategy based on input parameters. - The parameters being optimized are:
breakout_threshold
: The percentage change threshold to buy (currently set at 3%).breakdown_threshold
: The percentage change threshold to sell (currently set at -3%).upper_percentage
: The percentage of the day range within which the stock must close to trigger a breakout.
- The objective of the optimization is to minimize volatility and maximize returns, which leads to a smoother equity curve.
- We define a function
Optimized Conditions:
- After optimization, the best values for the breakout threshold, breakdown threshold, and upper percentage are used to run the strategy.
Plot and Output:
- The plot displays the optimized buy and sell signals on the price chart and the smoother equity curve based on the optimized conditions.
Customization:
You can adjust the upper/lower bounds in lower_bounds
and upper_bounds
to explore different ranges of thresholds. The DEoptim
algorithm can also be replaced with grid search or another optimization method if desired.
# Required Libraries
install.packages("DEoptim")
library(quantmod)
library(DEoptim) # For optimization
library(dplyr)
library(ggplot2)
# Step 1: Download GRSE.NS data
symbol <- "GRSE.NS"
getSymbols(symbol, from = "2010-01-01", to = Sys.Date())
grse_data <- data.frame(date = index(GRSE.NS), coredata(GRSE.NS))
# Step 2: Define the function for the trading strategy
trading_strategy <- function(params) {
breakout_threshold <- params[1] # Buy on breakout threshold
breakdown_threshold <- params[2] # Sell on breakdown threshold
upper_percentage <- params[3] # Upper day range percentage
# Calculate breakout and breakdown conditions based on parameters
grse_data <- grse_data %>%
mutate(
perc_change = (GRSE.NS.Close - lag(GRSE.NS.Close)) / lag(GRSE.NS.Close) * 100,
day_range = GRSE.NS.High - GRSE.NS.Low,
upper_condition = GRSE.NS.High - GRSE.NS.Close <= upper_percentage * day_range,
breakout = ifelse(perc_change >= breakout_threshold & upper_condition, TRUE, FALSE),
breakdown = ifelse(perc_change <= breakdown_threshold, TRUE, FALSE)
)
# Step 3: Trading strategy: Buy on breakout, sell on breakdown
trades <- data.frame(buy_date = as.Date(character()), buy_price = numeric(),
sell_date = as.Date(character()), sell_price = numeric(),
return = numeric(), stringsAsFactors = FALSE)
position_open <- FALSE
capital <- 100000 # Initial capital
equity_curve <- rep(capital, nrow(grse_data))
for (i in 2:nrow(grse_data)) {
# Skip if breakout or breakdown is NA
if (is.na(grse_data$breakout[i]) | is.na(grse_data$breakdown[i])) next
# Buy on breakout
if (grse_data$breakout[i] && !position_open) {
buy_price <- grse_data$GRSE.NS.Close[i]
position_open <- TRUE
}
# Sell on breakdown
if (position_open && grse_data$breakdown[i]) {
sell_price <- grse_data$GRSE.NS.Close[i]
return_trade <- (sell_price - buy_price) / buy_price
capital <- capital * (1 + return_trade)
position_open <- FALSE
}
# Update equity curve
equity_curve[i] <- capital
}
# Return objective to minimize: negative total return and volatility
total_return <- (capital - 100000) / 100000
volatility <- sd(diff(equity_curve[equity_curve > 0])) / mean(equity_curve)
# Minimize the negative of total return and volatility (for a smoother curve)
return(-total_return + volatility)
}
# Step 4: Use DEoptim for optimization
lower_bounds <- c(1, -5, 0.1) # Lower bounds for breakout, breakdown, and upper_percentage
upper_bounds <- c(5, -1, 0.5) # Upper bounds for breakout, breakdown, and upper_percentage
# Run optimization
optim_results <- DEoptim(trading_strategy, lower = lower_bounds, upper = upper_bounds,
control = list(itermax = 50))
# Extract optimized parameters
best_params <- optim_results$optim$bestmem
breakout_threshold <- best_params[1]
breakdown_threshold <- best_params[2]
upper_percentage <- best_params[3]
# Step 5: Run the optimized trading strategy and plot results
grse_data <- grse_data %>%
mutate(
perc_change = (GRSE.NS.Close - lag(GRSE.NS.Close)) / lag(GRSE.NS.Close) * 100,
day_range = GRSE.NS.High - GRSE.NS.Low,
upper_condition = GRSE.NS.High - GRSE.NS.Close <= upper_percentage * day_range,
breakout = ifelse(perc_change >= breakout_threshold & upper_condition, TRUE, FALSE),
breakdown = ifelse(perc_change <= breakdown_threshold, TRUE, FALSE)
)
# Trading strategy: Buy on breakout, sell on breakdown
trades <- data.frame(buy_date = as.Date(character()), buy_price = numeric(),
sell_date = as.Date(character()), sell_price = numeric(),
return = numeric(), stringsAsFactors = FALSE)
position_open <- FALSE
capital <- 100000 # Initial capital
equity_curve <- data.frame(date = grse_data$date, equity = capital)
for (i in 2:nrow(grse_data)) {
# Skip if breakout or breakdown is NA
if (is.na(grse_data$breakout[i]) | is.na(grse_data$breakdown[i])) next
# Buy on breakout
if (grse_data$breakout[i] && !position_open) {
buy_price <- grse_data$GRSE.NS.Close[i]
buy_date <- grse_data$date[i]
position_open <- TRUE
}
# Sell on breakdown
if (position_open && grse_data$breakdown[i]) {
sell_price <- grse_data$GRSE.NS.Close[i]
sell_date <- grse_data$date[i]
return_trade <- (sell_price - buy_price) / buy_price
capital <- capital * (1 + return_trade)
trades <- rbind(trades, data.frame(buy_date = buy_date, buy_price = buy_price,
sell_date = sell_date, sell_price = sell_price,
return = return_trade))
position_open <- FALSE
}
# Update equity curve
equity_curve$equity[i] <- capital
}
# Step 6: Plot the trades and equity curve
# Plot trades on price chart
ggplot(grse_data, aes(x = date, y = GRSE.NS.Close)) +
geom_line() +
geom_point(data = trades, aes(x = buy_date, y = buy_price), color = "green", size = 3, shape = 17) +
geom_point(data = trades, aes(x = sell_date, y = sell_price), color = "red", size = 3, shape = 18) +
ggtitle("GRSE.NS Price with Optimized Breakout Buy (Green) and Breakdown Sell (Red)") +
xlab("Date") + ylab("Price") +
theme_minimal()
# Plot equity curve
ggplot(equity_curve, aes(x = date, y = equity)) +
geom_line(color = "blue") +
ggtitle("Equity Curve (Optimized Compounded)") +
xlab("Date") + ylab("Equity") +
theme_minimal()
# Display trades table
print(trades)
Friday, October 4, 2024
Exploring Models on GDP Growth
We can use the Solow Growth Model as a simple example, which assumes that output (GDP) is determined by the Cobb-Douglas production function:
Y(t)=A(t)⋅K(t)α⋅L(t)1−αWhere:
- is the output at time t,
- is the level of technology (or productivity),
- is the labor input,
- is the capital's share of income.
Breakdown of Key Variables:
- Savings rate (s): Determines how much of the economy’s output is invested back into capital. Higher savings rates lead to higher levels of capital and output in the steady state.
- Depreciation rate (δ): Capital wears out over time, and the economy must invest enough to replace depreciated capital.
- Technological progress (γ): The key driver of long-term economic growth. Technological improvements increase productivity, allowing the economy to produce more output with the same inputs.
- Labor growth (η): Population and labor force growth influence how fast the economy needs to accumulate capital to keep up with a growing workforce.
Steps to Simulate Economic Growth:
- Define Initial Parameters: Set initial values for capital, labor, and productivity.
- Simulate Growth Over Time: Use equations to update capital, labor, and productivity at each time step.
- Plot the Results: Visualize the simulated economic growth using
ggplot2
.
Types of Shocks:
- Productivity Shock: A random shock that affects the level of productivity (e.g., technological innovation or a recession).
- Capital Shock: A random shock to the capital accumulation process (e.g., natural disasters that destroy capital).
- Labor Shock: A random shock to labor growth (e.g., demographic changes or pandemic).
We'll implement a random productivity shock in this example. Each period, the productivity A(t) will be multiplied by a random factor drawn from a normal distribution to simulate positive or negative shocks.
Example Output:
- With a low shock volatility, you will see a smooth GDP curve as the economy grows steadily.
- As you increase the shock volatility, you will notice more fluctuations and random jumps in GDP growth, simulating unpredictable events.
Wednesday, October 2, 2024
The revolutionary use of R in data analysis to explore the stock market
This is what shows up when you search "what is R" on Google. I must say, it is truly out of the world, that you can run codes and backtest your hypotheses. Being from Mechanical Engineering background, I find coding to be a meticulous subject for me to master, respecc to all those CSE bros and sis' who do it. But with the advent of CHATGPT, and R, it is way way easier to just give your propositions, run the GPT and get codes to substitute in R studio to create visualizations.
Saturday, September 28, 2024
Startups & Manufacturing Development in Defence
https://www.youtube.com/shorts/hexQSduf7p4
Wednesday, September 25, 2024
Remedy for Choppy names?
For choppy names like NEWGEN, extremely low risk entry, here for e.g. post gap down, a MB is formed with 3.87% day move, below a key MA.
-
This would primarily be designed for swing trades. Large Cap allocation for them is going to be good. However, a part of the portfolio in mi...