import numpy as np
import pandas as pd
import random
def initialize_population(population_size, num_weights):
population = []
for i in range(population_size):
weights = np.random.rand(num_weights)
population.append(weights)
return population
def calculate_fitness(weights, returns):
strategy_returns = returns.dot(weights)
fitness = np.prod(strategy_returns + 1) - 1
return fitness
def select_parents(population, returns, num_parents):
fitness_values = []
for i in range(len(population)):
fitness_values.append(calculate_fitness(population[i], returns))
sorted_indices = np.argsort(fitness_values)[::-1]
parents = [population[sorted_indices[i]] for i in range(num_parents)]
return parents
def crossover(parents, num_offspring):
offspring = []
for i in range(num_offspring):
parent1 = parents[i % len(parents)]
parent2 = parents[(i + 1) % len(parents)]
offspring.append(np.mean([parent1, parent2], axis=0))
return offspring
def mutate(offspring, mutation_probability):
for i in range(len(offspring)):
for j in range(len(offspring[i])):
if np.random.rand() < mutation_probability:
offspring[i][j] = np.random.rand()
return offspring
def evolve(population, returns, num_parents, num_offspring, mutation_probability):
parents = select_parents(population, returns, num_parents)
offspring = crossover(parents, num_offspring)
offspring = mutate(offspring, mutation_probability)
new_population = parents + offspring
return new_population
def run_genetic_algorithm(returns, population_size, num_parents, num_offspring,
mutation_probability, num_generations):
num_weights = returns.shape[1]
population = initialize_population(population_size, num_weights)
for i in range(num_generations):
population = evolve(population, returns, num_parents, num_offspring, mutation_probability)
return population[0]
# Load the data
data = pd.read_csv("data.csv")
# Calculate returns
returns = data.pct_change().dropna().values
# Run the genetic algorithm
weights = run_genetic_algorithm(returns, population_size=100, num_parents=20,
num_offspring=80, mutation_probability=0.1, num_generations=100)
# Calculate the strategy returns
strategy_returns = returns.dot(weights)
# Plot the strategy returns
plt.plot(np.cumprod(strategy_returns + 1) - 1)
plt.show()