Compare commits
1
Commits
main
..
3edb1bab6d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3edb1bab6d |
@@ -1,21 +0,0 @@
|
|||||||
Actions #,Coût par action (en euros),Bénéfice (après 2 ans)
|
|
||||||
Action-1,20,5%
|
|
||||||
Action-2,30,10%
|
|
||||||
Action-3,50,15%
|
|
||||||
Action-4,70,20%
|
|
||||||
Action-5,60,17%
|
|
||||||
Action-6,80,25%
|
|
||||||
Action-7,22,7%
|
|
||||||
Action-8,26,11%
|
|
||||||
Action-9,48,13%
|
|
||||||
Action-10,34,27%
|
|
||||||
Action-11,42,17%
|
|
||||||
Action-12,110,9%
|
|
||||||
Action-13,38,23%
|
|
||||||
Action-14,14,1%
|
|
||||||
Action-15,18,3%
|
|
||||||
Action-16,8,8%
|
|
||||||
Action-17,4,12%
|
|
||||||
Action-18,10,14%
|
|
||||||
Action-19,24,21%
|
|
||||||
Action-20,114,18%
|
|
||||||
|
@@ -1,77 +1,3 @@
|
|||||||
# AlgoInvest&Trade
|
# Projet7
|
||||||
|
|
||||||
Déterminer un choix optimal d'actions caractérisées par un coût et un rendement, en fonction d'un coût maximum pour un profit maximal
|
Solve problems using algorithms
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
Ces instructions vous permettent de :
|
|
||||||
- récupérer le programme,
|
|
||||||
- d'installer l'environnement nécessaire à son exécution,
|
|
||||||
- de l'exécuter,
|
|
||||||
- d'en connaitre le résultat
|
|
||||||
|
|
||||||
|
|
||||||
### Pré-requis
|
|
||||||
|
|
||||||
```
|
|
||||||
paquets : python 3.11, python3.11-venv, git
|
|
||||||
modules : csv
|
|
||||||
```
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
1. créer l'environnement virtuel :
|
|
||||||
```
|
|
||||||
python3.11 -m venv env
|
|
||||||
source env/bin/activate
|
|
||||||
```
|
|
||||||
2. cloner le dépôt :
|
|
||||||
```
|
|
||||||
git clone https://mcstn.fr/gitea/Yann/Projet7.git
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Exécution
|
|
||||||
|
|
||||||
Pour l'algorithme bruteforce sur le dataset0,
|
|
||||||
exécuter la commande :
|
|
||||||
```
|
|
||||||
python3 bruteforce.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Pour l'algorithme de DP, executer la commande :
|
|
||||||
```
|
|
||||||
python3 optimized.py
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Résultat
|
|
||||||
|
|
||||||
Optimized traite par défaut les datasets 1 et 2;
|
|
||||||
Décommenter la ligne du dataset0 dans le main() si besoin
|
|
||||||
```
|
|
||||||
$ time python optimized.py
|
|
||||||
|
|
||||||
DATASET 1
|
|
||||||
Cost: 499.43 €
|
|
||||||
Profit: 196.84 €
|
|
||||||
Shares : ['Share-HITN', 'Share-GRUT']
|
|
||||||
|
|
||||||
DATASET 2
|
|
||||||
Cost: 497.67 €
|
|
||||||
Profit: 194.90 €
|
|
||||||
Shares : ['Share-GEBJ', 'Share-LFXB', 'Share-FWBE', 'Share-PLLK', 'Share-ZKSN', 'Share-ZOFA', 'Share-PATS', 'Share-DWSK', 'Share-ALIY', 'Share-ECAQ', 'Share-FAPS', 'Share-JGTW', 'Share-QLWT', 'Share-OPBR', 'Share-ANFX', 'Share-IJFT', 'Share-JWGF']
|
|
||||||
|
|
||||||
real 0m0,852s
|
|
||||||
user 0m0,832s
|
|
||||||
sys 0m0,018s
|
|
||||||
```
|
|
||||||
## Auteur
|
|
||||||
|
|
||||||
Yann <yann@needsome.coffee>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
N/A
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
import csv
|
|
||||||
|
|
||||||
MAX_COST = 500
|
|
||||||
FILE = "Liste+dactions+-+P7+Python+-+Feuille+1.csv"
|
|
||||||
|
|
||||||
def listFromFile(csv_file):
|
|
||||||
"""
|
|
||||||
get data from a csv file and :
|
|
||||||
converts numbers, remove first title line
|
|
||||||
returns a list including name, cost: int, roi: float
|
|
||||||
"""
|
|
||||||
liste = []
|
|
||||||
with open(csv_file) as file:
|
|
||||||
data = csv.reader(file)
|
|
||||||
for i in data:
|
|
||||||
liste.append(i)
|
|
||||||
liste.pop(0)
|
|
||||||
for item in liste:
|
|
||||||
item[1] = int(item[1])
|
|
||||||
item[2] = item[1] * float(item[2].strip("%")) / 100
|
|
||||||
return liste
|
|
||||||
|
|
||||||
|
|
||||||
def powerset(itemList):
|
|
||||||
"""
|
|
||||||
Generate every subset (combination) for a given list
|
|
||||||
:param itemList: a list of items
|
|
||||||
:return: a list of combinations(lists)
|
|
||||||
"""
|
|
||||||
result = [[]]
|
|
||||||
for item in itemList:
|
|
||||||
newsubsets = [subset + [item] for subset in result]
|
|
||||||
result.extend(newsubsets)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def transformData(dataset):
|
|
||||||
"""
|
|
||||||
Transform in a list of dict with computed values as gain, ratio
|
|
||||||
Sorted by gain
|
|
||||||
:param dataset: list of items
|
|
||||||
:return: a sorted list of dict
|
|
||||||
"""
|
|
||||||
tmpset = [{'nom': x[0], 'cout': x[1],
|
|
||||||
'rendement': x[2],
|
|
||||||
'gain': x[1] * x[2] / 100,
|
|
||||||
'ratio1': x[2] / x[1],
|
|
||||||
'ratio2': (x[1] * x[2] / 100) / x[1]}
|
|
||||||
for x in dataset if x[1] > 0.0 and x[2] > 0.0]
|
|
||||||
|
|
||||||
return sorted(tmpset, key=lambda x: x['gain'], reverse=True)
|
|
||||||
|
|
||||||
|
|
||||||
def selectActions(actionList, maximal_cost):
|
|
||||||
"""
|
|
||||||
select combination corresponding to max cost
|
|
||||||
:param actionList: list of combinations
|
|
||||||
:param maximal_cost: maximal cost
|
|
||||||
:return: a list of selected items
|
|
||||||
"""
|
|
||||||
best = []
|
|
||||||
for i in actionList:
|
|
||||||
cost = 0
|
|
||||||
gain = 0
|
|
||||||
for action in i:
|
|
||||||
cost += action[1]
|
|
||||||
gain += action[2]
|
|
||||||
if cost < int(maximal_cost):
|
|
||||||
best.append((gain, cost, i))
|
|
||||||
|
|
||||||
sortedBest = sorted(best, key=lambda k: k[0], reverse=True)
|
|
||||||
|
|
||||||
return sortedBest.pop(0)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
actions = listFromFile(FILE)
|
|
||||||
power_actions = powerset(actions)
|
|
||||||
selected_actions = selectActions(power_actions, MAX_COST)
|
|
||||||
# tri des actions sur le rendement
|
|
||||||
print("Cost:", selected_actions[1], "€")
|
|
||||||
print("Profit: %.2f €" % selected_actions[0])
|
|
||||||
print(f"Shares: {[x[0] for x in selected_actions[2]]}")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
-109
@@ -1,109 +0,0 @@
|
|||||||
import csv
|
|
||||||
|
|
||||||
MAX_COST = 500
|
|
||||||
DATASET1 = "dataset1_Python+P7.csv"
|
|
||||||
DATASET2 = "dataset2_Python+P7.csv"
|
|
||||||
DATASET0 = "Liste+dactions+-+P7+Python+-+Feuille+1.csv"
|
|
||||||
|
|
||||||
|
|
||||||
def listFromFile(csv_file):
|
|
||||||
"""
|
|
||||||
Extract and format data from file(csv)
|
|
||||||
:param csv_file: full path
|
|
||||||
:return: a list of items
|
|
||||||
"""
|
|
||||||
liste = []
|
|
||||||
with open(csv_file) as file:
|
|
||||||
data = csv.reader(file)
|
|
||||||
for i in data:
|
|
||||||
liste.append(i)
|
|
||||||
liste.pop(0)
|
|
||||||
for item in liste:
|
|
||||||
item[1] = float(item[1])
|
|
||||||
if item[2][-1] == "%":
|
|
||||||
item[2] = item[2].strip("%")
|
|
||||||
item[2] = float(item[2])
|
|
||||||
return liste
|
|
||||||
|
|
||||||
|
|
||||||
def transformData(dataset):
|
|
||||||
"""
|
|
||||||
Transform in a list of dict with computed values as gain, ratio
|
|
||||||
Sorted by gain
|
|
||||||
:param dataset: list of items
|
|
||||||
:return: a sorted list of dict
|
|
||||||
"""
|
|
||||||
tmpset = [{'nom': x[0], 'cout': x[1],
|
|
||||||
'rendement': x[2],
|
|
||||||
'gain': x[1] * x[2] / 100,
|
|
||||||
'ratio1': x[2] / x[1],
|
|
||||||
'ratio2': (x[1] * x[2] / 100) / x[1]}
|
|
||||||
for x in dataset if x[1] > 0.0 and x[2] > 0.0]
|
|
||||||
|
|
||||||
return sorted(tmpset, key=lambda x: x['gain'], reverse=True)
|
|
||||||
|
|
||||||
|
|
||||||
def get_results(filepath, maximum, nbr):
|
|
||||||
"""
|
|
||||||
load, transform data then run the algorithm and print results
|
|
||||||
:param filepath: full path to csv
|
|
||||||
:param maximum: maximum cost
|
|
||||||
:param nbr: set number
|
|
||||||
:return: print results
|
|
||||||
"""
|
|
||||||
|
|
||||||
action_list = transformData(listFromFile(filepath))
|
|
||||||
maximum_gain, selection = sacADosFloat(action_list, maximum)
|
|
||||||
|
|
||||||
print("\nDATASET", nbr)
|
|
||||||
print(f"Cost: {sum(x['cout'] for x in selection):.2f} €")
|
|
||||||
print("Profit: %.2f €" % maximum_gain)
|
|
||||||
print(f"Shares : {[x['nom'] for x in selection]}")
|
|
||||||
|
|
||||||
|
|
||||||
def sacADosFloat(actions, maximum_cost):
|
|
||||||
"""
|
|
||||||
Use dynamic approach
|
|
||||||
:param actions: a list of dict with minimum key as cost and gain
|
|
||||||
:param maximum_cost: the constraint, our max cost
|
|
||||||
:return: maximum gain: int, selected items: list
|
|
||||||
"""
|
|
||||||
n = len(actions)
|
|
||||||
table = [[0.0 for x in range(int(maximum_cost) + 1)] for x in range(n + 1)]
|
|
||||||
|
|
||||||
# Dynamic programing table
|
|
||||||
for i in range(n + 1):
|
|
||||||
for w in range(int(maximum_cost) + 1):
|
|
||||||
if i == 0 or w == 0:
|
|
||||||
table[i][w] = 0.0
|
|
||||||
elif actions[i-1]['cout'] <= w:
|
|
||||||
table[i][w] = (
|
|
||||||
max(
|
|
||||||
actions[i-1]['gain'] +
|
|
||||||
table[i-1][int(w-actions[i-1]['cout'])],
|
|
||||||
table[i-1][w]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
table[i][w] = table[i-1][w]
|
|
||||||
|
|
||||||
# Selection
|
|
||||||
w = maximum_cost
|
|
||||||
selected_actions = []
|
|
||||||
for i in range(n, 0, -1):
|
|
||||||
if table[i][int(w)] != table[i-1][int(w)]:
|
|
||||||
selected_actions.append(actions[i-1])
|
|
||||||
w -= actions[i-1]['cout']
|
|
||||||
|
|
||||||
return table[n][int(maximum_cost)], selected_actions
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# get_results(DATASET0, MAX_COST, 0)
|
|
||||||
get_results(DATASET1, MAX_COST, 1)
|
|
||||||
get_results(DATASET2, MAX_COST, 2)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user