장유진

종목 선별 및 백테스팅 프로그램 최종본

Showing 46 changed files with 241 additions and 300 deletions
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/../../../../../../../:\Users\YuJin\Desktop\캡디2\stock_pbr_test\.idea/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/result_kr.csv" charset="x-windows-949" />
<file url="file://$PROJECT_DIR$/result_kr1.csv" charset="x-windows-949" />
</component>
</project>
\ No newline at end of file
from Investment.Strategy.StrategyBase import StrategyBase
from Investment.Strategy.FinancialStatementsStrategyBase import FinancialStatementsStrategyBase
from datetime import date
class Strategy(FinancialStatementsStrategyBase):
def __init__(self):
super().__init__()
def __repr__(self):
return self.Name
def setStrategy(self, per=None, pbr_up=None, pbr_down=None, roe=None, order='PER'):
super().setStrategy()
self.Name = 'PER_ROE_V1.0'
self.NumberOfStocks = 10
self.AdditionalFinancialStatementsItem = ['PER', 'PBR', 'ROE']
# self.FinancialStatementsCondition = '(PER > 6) and (ROE > 10) and (PBR > 0.5) and (PBR < 1)'
self.setFinancialStatementsCondition(per, pbr_up, pbr_down, roe)
print(self.FinancialStatementsCondition)
# self.FinancialStatementsCondition = '(PER > 0) and (PER < 20) and (ROE > 10)'
# self.FinancialStatementsCondition = '(PBR < 1)'
self.FinancialStatementsYear = 2016
self.FinancialStatementsQuater = 4
self.FinancialStatementsDiv = 'CFS'
self.StockDate = date(2017, 4, 10)
self.FinancialStatementsSearchTarget = ['StockCode', 'Equity', 'ProfitLoss']
self.StockSearchTarget = ['MarketCapitalization']
self.FinancialStatementsOrderBy = [order]
if order == 'PER':
self.FinancialStatementsOrderMethod = 'asc'
else:
self.FinancialStatementsOrderMethod = 'desc'
# self.FinancialStatementsOrderBy.append('ROE')
# self.FinancialStatementsOrderMethod = 'desc'
def setFinancialStatementsCondition(self, per, pbr_up, pbr_down, roe):
self.FinancialStatementsCondition = ''
if per is not None:
self.FinancialStatementsCondition += f'(PER > {per})'
if pbr_up:
if len(self.FinancialStatementsCondition) == 0:
self.FinancialStatementsCondition += f'(PBR > {pbr_up})'
else:
self.FinancialStatementsCondition += f' and (PBR > {pbr_up})'
if pbr_down:
if len(self.FinancialStatementsCondition) == 0:
self.FinancialStatementsCondition += f'(PBR < {pbr_down})'
else:
self.FinancialStatementsCondition += f' and (PBR < {pbr_down})'
if roe:
if len(self.FinancialStatementsCondition) == 0:
self.FinancialStatementsCondition += f'(ROE > {roe})'
else:
self.FinancialStatementsCondition += f' and (ROE > {roe})'
def searchData(self):
return FinancialStatementsStrategyBase.searchData(self)
def setAdditionalData(self):
return FinancialStatementsStrategyBase.setAdditionalData(self)
import datetime
import Strategy
import Trading
import Verification
import sys
import DataProvider
def single():
record = [0]
# record = [18.91309, 17.8967, 17.14154, 16.07653, 16.03074]
strategy_record = [[3, 0.7000000000000001, 10, 18.91309], [3, 0.7000000000000001, 11, 17.8967],
[3, 0.8, 11, 17.14154], [4, 0.7000000000000001, 11, 16.07653],
[3, 0.7000000000000001, 5, 16.03074]]
st = Strategy.Strategy()
tr = Trading.Trading()
ve = Verification.Verification()
db = DataProvider.DataProvider()
if db.initialize():
print('db connection')
# print(db.findSP(['StockDate','Open'], '004990', '2019-04-11', '2019-12-31'))
st.db = db
st.setStrategy(10, 0, 1.5, 0)
if (st.searchData() == False):
print("st.searchData error")
sys.exit(-1)
if (st.setAdditionalData() == False):
print("st.setAdditionalData error")
sys.exit(-1)
tr.df_all = st.df_all
tr.db = db
tr.setTrading()
if (tr.doTrading() == False):
print("tr.doTrading error")
sys.exit(-1)
ve.TotalInvestmentAmount = tr.TotalInvestmentAmount
ve.df_all = tr.df_all
ve.setVerification()
ve.doVerification()
ve.saveResult()
# ve.saveResulToJSON()
r, Yield = ve.saveSummary(record, 0)
else:
print("db error")
db.close()
def multi():
start = datetime.datetime.now()
record = [0]
strategy_record = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
num = 0
st = Strategy.Strategy()
tr = Trading.Trading()
ve = Verification.Verification()
db = DataProvider.DataProvider()
for per in range(8):
pbr = 1
while pbr > 0.3:
for roe in range(10, 20):
if db.initialize():
print('db connection')
# print(db.findSP(['StockDate','Open'], '004990', '2019-04-11', '2019-12-31'))
st.db = db
else:
print("db error")
st.setStrategy(per, pbr, 1.2, roe)
if (st.searchData() == False):
print("st.searchData error")
sys.exit(-1)
if (st.setAdditionalData() == False):
print("st.setAdditionalData error")
sys.exit(-1)
tr.df_all = st.df_all
tr.db = db
tr.setTrading()
if (tr.doTrading() == False):
print("tr.doTrading error")
sys.exit(-1)
ve.TotalInvestmentAmount = tr.TotalInvestmentAmount
ve.df_all = tr.df_all
ve.setVerification()
ve.doVerification()
ve.saveResult()
# ve.saveResulToJSON()
r, Yield = ve.saveSummary(record, num)
if r:
for i in range(5):
if strategy_record[i][3] < Yield:
strategy_record.insert(i, [per, pbr, roe, Yield])
break
strategy_record.pop()
print(record, strategy_record)
num += 1
pbr -= 0.1
db.close()
end = datetime.datetime.now()
print('time: ', end - start)
print(strategy_record)
if __name__ == '__main__':
single()
# multi()
,StockCode,StockName,Equity,ProfitLoss,PER,MarketCapitalization,PBR,BuyingPrice,SellPrice,BuyingAmount,ProfitLossByStock,InvestmentAmount,Balance,Yield
0,002030,아세아,1225090202229.0,67565442549.0,3.171475522336699,214282147200.0,0.17491132229294026,97800.0,125000.0,102.0,27200.0,9975600.0,12750000.0,27.811860940695297
1,058650,세아홀딩스,2924149208280.0,161892654956.0,3.1872971639154417,516000000000.0,0.17646158360828446,126000.0,133500.0,79.0,7500.0,9954000.0,10546500.0,5.952380952380952
2,001940,KISCO홀딩스,1273968329992.0,77864434261.0,2.956621941518533,230215694800.0,0.18070754930104554,63000.0,65300.0,158.0,2300.0,9954000.0,10317400.0,3.650793650793651
3,000880,한화,14227936000000.0,1288691000000.0,2.0445549284118534,2634799535250.0,0.1851849442709048,35700.0,38350.0,280.0,2650.0,9996000.0,10738000.0,7.42296918767507
4,007860,서연,1072030023657.0,132366474007.0,1.7827205413624674,235972432200.0,0.22011737264132844,10150.0,6480.0,985.0,-3670.0,9997750.0,6382800.0,-36.1576354679803
5,019010,베뉴지,236756098347.0,12783309005.0,4.769735283419287,60973000000.0,0.25753507692391236,12850.0,12800.0,778.0,-50.0,9997300.0,9958400.0,-0.38910505836575876
6,092230,KPX홀딩스,936238978408.0,53425479418.0,4.894772873332309,261505587400.0,0.2793149969516004,63000.0,63000.0,158.0,0.0,9954000.0,9954000.0,0.0
7,023600,삼보판지,329937058742.0,40288485800.0,2.380332695452158,95900000000.0,0.29066149878904834,6860.0,9790.0,1457.0,2930.0,9995020.0,14264030.0,42.711370262390666
8,033160,엠케이전자,593852198159.0,74507668124.0,2.391281644105155,178168819130.0,0.30002215986122605,8360.0,10250.0,1196.0,1890.0,9998560.0,12259000.0,22.607655502392344
9,021820,세원정공,569620475934.0,56809840064.0,3.309285852384124,188000000000.0,0.3300443153693494,18350.0,13700.0,544.0,-4650.0,9982400.0,7452800.0,-25.340599455040874
10,,,,,,,,,,,,,104622930.0,4.8183
,StockCode,StockName,Equity,ProfitLoss,PER,MarketCapitalization,PBR,ROE,BuyingPrice,SellPrice,BuyingAmount,ProfitLossByStock,InvestmentAmount,Balance,Yield
0,008370,원풍,75070172618.0,5235935528.0,10.049779971240318,52620000000.0,0.7009441721648979,6.974721577694294,4505.0,4050.0,2219.0,-455.0,9996595.0,8986950.0,-10.099889012208656
1,119860,다나와,65170505380.0,8935066130.0,10.052978437217229,89824027140.0,1.378292628179708,13.71029130110453,6930.0,17950.0,1443.0,11020.0,9999990.0,25901850.0,159.01875901875903
2,014970,삼륭물산,65649138867.0,9219435245.0,10.073013968004718,92867500000.0,1.4146034754262697,14.043497605776448,6470.0,5500.0,1545.0,-970.0,9996150.0,8497500.0,-14.992272024729521
3,004430,송원산업,354189000000.0,42244000000.0,10.084272322696714,426000000000.0,1.2027476855577106,11.926965546643178,18500.0,29150.0,540.0,10650.0,9990000.0,15741000.0,57.567567567567565
4,017040,광명전기,98063359627.0,11593891042.0,10.111208407111059,117228248575.0,1.1954337381555842,11.822857269115863,2800.0,3620.0,3571.0,820.0,9998800.0,12927020.0,29.28571428571429
5,027710,팜스토리,166916854808.0,12896142588.0,10.173269575747343,131195935035.0,0.7859957293462735,7.726087699671845,1515.0,1300.0,6600.0,-215.0,9999000.0,8580000.0,-14.19141914191419
6,069510,에스텍,124146823459.0,14748421661.0,10.208414395835193,150558000000.0,1.2127414605152778,11.879822012418003,14150.0,10800.0,706.0,-3350.0,9989900.0,7624800.0,-23.674911660777383
7,012200,계양전기,179133111299.0,17233731189.0,10.214851216454122,176040000000.0,0.9827328890981124,9.620628516988308,5500.0,4140.0,1818.0,-1360.0,9999000.0,7526520.0,-24.727272727272727
8,204320,만도,1515053750297.0,210079641643.0,10.237241834478636,2150636096000.0,1.4195114170559329,13.866151059117046,231500.0,231000.0,43.0,-500.0,9954500.0,9933000.0,-0.21598272138228944
9,098660,에스티오,33858491829.0,3213669838.0,10.254857832723014,32955727310.0,0.9733371313890958,9.491473672927961,3865.0,2820.0,2587.0,-1045.0,9998755.0,7295340.0,-27.037516170763258
10,,,,,,,,,,,,,,113013980.0,13.09129
......@@ -4,6 +4,13 @@
<inspection_tool class="PyChainedComparisonsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoreConstantInTheMiddle" value="true" />
</inspection_tool>
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="N802" />
</list>
</option>
</inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (stock_pbr_test)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (stock_pbr_test (1))" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
......
......@@ -2,7 +2,7 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/stock_pbr_test.iml" filepath="$PROJECT_DIR$/.idea/stock_pbr_test.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/stock_pbr_test (1).iml" filepath="$PROJECT_DIR$/.idea/stock_pbr_test (1).iml" />
</modules>
</component>
</project>
\ No newline at end of file
......
......@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.9 (stock_pbr_test)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.9 (stock_pbr_test (1))" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="08cfd845-d1af-47c5-9eaf-7ec10bc089e6" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="GitSEFilterConfiguration">
<file-type-list>
<filtered-out-file-type name="LOCAL_BRANCH" />
<filtered-out-file-type name="REMOTE_BRANCH" />
<filtered-out-file-type name="TAG" />
<filtered-out-file-type name="COMMIT_BY_MESSAGE" />
</file-type-list>
</component>
<component name="ProjectId" id="1rhNXDA6G2BEILfU2FcLF2UeeII" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../stock_pbr_test" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="08cfd845-d1af-47c5-9eaf-7ec10bc089e6" name="Default Changelist" comment="" />
<created>1619424399162</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1619424399162</updated>
<workItem from="1619424400378" duration="55000" />
<workItem from="1620378646442" duration="2361000" />
<workItem from="1621433178774" duration="882000" />
<workItem from="1621502235218" duration="1898000" />
<workItem from="1621509254458" duration="559000" />
<workItem from="1622283631431" duration="5501000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>
\ No newline at end of file
......@@ -53,7 +53,7 @@ class DataProvider:
querystring = querystring + '"' + target + '",'
querystring = querystring[:-1]
querystring = querystring + 'from "StockPrice" ' + 'WHERE ' + '"id"=' + "'" + stockcode + stockdate + "'"
return self.DB.searchData(querystring, columns)
return self.DB.searchData(querystring, columns)
def findSP(self, columns: List[str], stockcode: str, stock_startdate: str, stock_enddate: str):
if( self.DB ):
......
from datetime import date
import pandas as pd
import sys
import sys
from Investment.Strategy.StrategyBase import StrategyBase
class FinancialStatementsStrategyBase(StrategyBase):
AdditionalFinancialStatementsItem = []
FinancialStatementsCondition = ''
......@@ -17,13 +16,13 @@ class FinancialStatementsStrategyBase(StrategyBase):
StockSearchTarget = []
FinancialStatementsOrderBy = []
FinancialStatementsOrderMethod = ''
df_fs = None
df_stock = None
df_company = None
def __init__(self):
super().__init__()
super().__init__
self.Division = "FinancialStatements"
def __repr__(self):
......@@ -34,10 +33,8 @@ class FinancialStatementsStrategyBase(StrategyBase):
def searchData(self):
try:
if self.df_fs is None:
self.df_fs = self.db.findFS(self.FinancialStatementsSearchTarget, self.FinancialStatementsYear,
self.FinancialStatementsQuater, self.FinancialStatementsDiv)
if self.df_fs is None:
self.df_fs = self.db.findFS(self.FinancialStatementsSearchTarget, self.FinancialStatementsYear, self.FinancialStatementsQuater, self.FinancialStatementsDiv)
if( self.df_fs is None) :
print('db query error')
sys.exit(1)
except:
......@@ -47,43 +44,54 @@ class FinancialStatementsStrategyBase(StrategyBase):
def setAdditionalData(self):
try:
for item in self.AdditionalFinancialStatementsItem:
for item in self.AdditionalFinancialStatementsItem:
self.df_fs[item] = 0
for item in self.StockSearchTarget:
for item in self.StockSearchTarget:
self.df_fs[item] = 0
for index, row in self.df_fs.iterrows():
self.df_stock = self.db.findSPbyID(self.StockSearchTarget, row['StockCode'],
self.StockDate.strftime("%Y-%m-%d"))
if self.df_stock is None:
self.df_stock = self.db.findSPbyID(self.StockSearchTarget, row['StockCode'], self.StockDate.strftime("%Y-%m-%d"))
if self.df_stock is None :
print('db query error')
else:
if self.df_stock.size < 1:
else :
if self.df_stock.size < 1 :
continue
for item in self.StockSearchTarget:
for item in self.StockSearchTarget:
self.df_fs.loc[index, item] = self.df_stock[item][0]
for item in self.AdditionalFinancialStatementsItem:
if item == 'PER':
if row["ProfitLoss"] != 0:
self.df_fs.loc[index, item] = self.df_fs.loc[index, 'MarketCapitalization'] / row[
"ProfitLoss"]
if row["ProfitLoss"] != 0 :
self.df_fs.loc[index, item] = self.df_fs.loc[index, 'MarketCapitalization']/row["ProfitLoss"]
elif item == 'PBR':
if row["Equity"] != 0:
self.df_fs.loc[index, item] = self.df_fs.loc[index, 'MarketCapitalization'] / row[
"Equity"]
if row["Equity"] != 0 :
self.df_fs.loc[index, item] = self.df_fs.loc[index, 'MarketCapitalization']/row["Equity"]
elif item == 'ROE':
if row["Equity"] != 0:
self.df_fs.loc[index, item] = float(row["ProfitLoss"]) / float(
row["Equity"]) * 100.00
if row["Equity"] != 0 :
self.df_fs.loc[index, item] = float(row["ProfitLoss"])/float(row["Equity"]) * 100.00
elif item == 'PSR':
if row["Revenue"] != 0 :
self.df_fs.loc[index, item] = self.df_fs.loc[index, 'MarketCapitalization']/row["Revenue"]
elif item == 'PCR':
if row["CashAndCashEquivalentsAtEndOfPeriodCf"] != 0 :
self.df_fs.loc[index, item] = self.df_fs.loc[index, 'MarketCapitalization']/row["CashAndCashEquivalentsAtEndOfPeriodCf"]
elif item == 'DR':
if row["Equity"] != 0 :
self.df_fs.loc[index, item] = float(row["Liabilities"])/float(row["Equity"]) * 100.00
elif item == 'OM':
if row["Revenue"] != 0 :
self.df_fs.loc[index, item] = float(row["OperatingIncomeLoss"])/float(row["Revenue"]) * 100.00
elif item == 'NPM':
if row["Revenue"] != 0 :
self.df_fs.loc[index, item] = float(row["ProfitLoss"])/float(row["Revenue"]) * 100.00
asc = True
if self.FinancialStatementsOrderMethod == 'asc':
asc = True
elif self.FinancialStatementsOrderMethod == 'desc':
asc = False
self.df_all = self.df_fs.query(self.FinancialStatementsCondition).sort_values(
by=self.FinancialStatementsOrderBy, ascending=asc).head(self.NumberOfStocks)
self.df_all.insert(1, 'StockName', '')
self.df_all = self.df_fs.query(self.FinancialStatementsCondition).sort_values(by=self.FinancialStatementsOrderBy, ascending=asc).head(self.NumberOfStocks)
self.df_all.insert(1,'StockName','')
self.df_all['StockName'] = ''
for index, row in self.df_all.iterrows():
......@@ -93,3 +101,4 @@ class FinancialStatementsStrategyBase(StrategyBase):
print("Unexpected error:", sys.exc_info()[0])
return False
return True
\ No newline at end of file
......
......@@ -34,7 +34,7 @@ class TradingBase:
if self.BuyingMethod == 1:
investmentAmount = self.TotalInvestmentAmount / self.NumberOfStocks
for index, row in self.df_all.iterrows():
self.df_stock = self.db.findSPbyID(self.StockBuyingSearchTarget, self.df_all.loc[index, 'StockCode'], self.BuyingDateTime[0].strftime("%Y-%m-%d"))
self.df_stock = self.db.findSPbyID(self.StockBuyingSearchTarget, self.df_all.loc[index, 'StockCode'], self.BuyingDateTime[0].strftime("%Y-%m-%d"))
if self.df_stock is None :
print('db query error')
else:
......@@ -42,7 +42,7 @@ class TradingBase:
continue
buyingPrice = self.df_stock[self.StockBuyingSearchTarget[0]][0]
self.df_stock = self.db.findSPbyID(self.StockSellSearchTarget, self.df_all.loc[index, 'StockCode'], self.SellDateTime[0].strftime("%Y-%m-%d"))
self.df_stock = self.db.findSPbyID(self.StockSellSearchTarget, self.df_all.loc[index, 'StockCode'], self.SellDateTime[0].strftime("%Y-%m-%d"))
if self.df_stock is None :
print('db query error')
else:
......@@ -54,7 +54,6 @@ class TradingBase:
self.df_all.loc[index, 'SellPrice'] = sellPrice
self.df_all.loc[index, 'BuyingAmount'] = int(investmentAmount / buyingPrice)
elif self.BuyingMethod == 2:
print('...')
else:
......
import pandas as pd
import json
class VerificationBase:
Name = ''
TotalInvestmentAmount = 0
Balance: int = 0
Yield: float = 0
df_all = None # type: pd
df_all = None # type: pd
db = None
def __init__(self):
......@@ -21,10 +20,10 @@ class VerificationBase:
print("setVerification")
def doVerification(self):
self.df_all['ProfitLossByStock'] = 0
self.df_all['InvestmentAmount'] = 0
self.df_all['Balance'] = 0
self.df_all['Yield'] = 0
self.df_all['ProfitLossByStock'] = 0
self.df_all['InvestmentAmount'] = 0
self.df_all['Balance'] = 0
self.df_all['Yield'] = 0
for index, row in self.df_all.iterrows():
buyingPrice = self.df_all.loc[index, 'BuyingPrice']
......@@ -32,22 +31,19 @@ class VerificationBase:
investmentCurrentAmount = self.df_all.loc[index, 'BuyingAmount'] * buyingPrice
self.df_all.loc[index, 'ProfitLossByStock'] = sellPrice - buyingPrice
self.df_all.loc[index, 'InvestmentAmount'] = investmentCurrentAmount
self.df_all.loc[index, 'Balance'] = investmentCurrentAmount + self.df_all.loc[index, 'ProfitLossByStock'] * \
self.df_all.loc[index, 'BuyingAmount']
self.df_all.loc[index, 'Yield'] = (float(self.df_all.loc[index, 'Balance']) - float(
investmentCurrentAmount)) / float(investmentCurrentAmount) * 100.00
self.df_all.loc[index, 'Balance'] = investmentCurrentAmount + self.df_all.loc[index, 'ProfitLossByStock'] * self.df_all.loc[index, 'BuyingAmount']
self.df_all.loc[index, 'Yield'] = (float(self.df_all.loc[index, 'Balance']) - float(investmentCurrentAmount))/float(investmentCurrentAmount) * 100.00
self.Balance = self.df_all['Balance'].sum()
investmentCurrentTotalAmount = self.df_all['InvestmentAmount'].sum()
self.df_all = self.df_all.append(pd.Series(), ignore_index=True)
self.df_all.loc[len(self.df_all) - 1, 'Balance'] = self.Balance
self.Yield = ((float(self.Balance) + float(self.TotalInvestmentAmount - investmentCurrentTotalAmount)) - float(
self.TotalInvestmentAmount)) / float(self.TotalInvestmentAmount) * 100.00
self.df_all.loc[len(self.df_all) - 1, 'Yield'] = self.Yield
self.df_all = self.df_all.append(pd.Series(), ignore_index = True)
self.df_all.loc[len(self.df_all)-1, 'Balance'] = self.Balance
self.Yield = ((float(self.Balance) + float(self.TotalInvestmentAmount - investmentCurrentTotalAmount)) - float(self.TotalInvestmentAmount))/float(self.TotalInvestmentAmount) * 100.00
self.df_all.loc[len(self.df_all)-1, 'Yield'] = self.Yield
def saveResult(self):
self.df_all.to_csv("result1.csv")
self.df_all.to_csv("result_kr1.csv", encoding='euc-kr')
self.df_all.to_csv("result.csv")
self.df_all.to_csv("result_kr.csv", encoding='euc-kr')
def saveResulToJSON(self):
result = self.df_all.to_json(orient="split")
......@@ -55,23 +51,9 @@ class VerificationBase:
with open("result.json", "w") as text_file:
text_file.write(json.dumps(parsed, indent=4, ensure_ascii=False))
def saveSummary(self, record, num):
self.Yield = round(self.Yield, 5)
if record[-1] < self.Yield:
if record[0] == 0:
record[0] = self.Yield
else:
for i in range(5):
if record[i] == self.Yield:
return False, 0
elif record[i] < self.Yield:
record.insert(i, self.Yield)
break
if len(record) > 5:
record.pop()
jsonobj = {"TotalInvestmentAmount": str(self.TotalInvestmentAmount), "Balance": str(self.Balance),
"Yield": str(self.Yield)}
with open(f"result_summary{num}.json", "w") as text_file:
text_file.write(json.dumps(jsonobj, indent=4))
return True, self.Yield
return False, 0
def saveSummary(self):
jsonobj = { "TotalInvestmentAmount" : str(self.TotalInvestmentAmount), "Balance" : str(self.Balance), "Yield": str(self.Yield)}
with open("result_summary.json", "w") as text_file:
text_file.write(json.dumps(jsonobj, indent=4))
......
from Investment.Strategy.FinancialStatementsStrategyBase import FinancialStatementsStrategyBase
from datetime import date
class Strategy(FinancialStatementsStrategyBase):
def __init__(self):
super().__init__
def __repr__(self):
return self.Name
def setStrategy(self):
super().setStrategy()
self.Name = 'PER_ROE_V1.0'
self.NumberOfStocks = 10
self.AdditionalFinancialStatementsItem.append('PER')
self.AdditionalFinancialStatementsItem.append('PBR')
self.AdditionalFinancialStatementsItem.append('ROE')
self.FinancialStatementsCondition = '(PER > 0) and (PBR < 0.7) and (ROE > 11)'
self.FinancialStatementsYear = 2016
self.FinancialStatementsQuater = 4
self.FinancialStatementsDiv = 'CFS'
self.StockDate = date(2017, 4, 10)
self.FinancialStatementsSearchTarget.append('StockCode')
self.FinancialStatementsSearchTarget.append('Equity')
self.FinancialStatementsSearchTarget.append('ProfitLoss')
self.FinancialStatementsSearchTarget.append('CashAndCashEquivalentsAtEndOfPeriodCf')
self.FinancialStatementsSearchTarget.append('Revenue')
self.StockSearchTarget.append('MarketCapitalization')
self.FinancialStatementsOrderBy.append('PER')
self.FinancialStatementsOrderMethod = 'asc'
def searchData(self):
return FinancialStatementsStrategyBase.searchData(self)
def setAdditionalData(self):
return FinancialStatementsStrategyBase.setAdditionalData(self)
from Investment.Trading.TradingBase import TradingBase
from datetime import date
class Trading(TradingBase):
def __init__(self):
super().__init__
def __repr__(self):
return self.Name
......@@ -12,14 +13,14 @@ class Trading(TradingBase):
super().setTrading()
self.Name = 'Split evenly'
self.TotalInvestmentAmount = 100000000
self.Method = 1 # 1 : "Split evenly",
self.Method = 1 # 1 : "Split evenly",
self.BuyingMethod = 1 # 1 : at once
self.BuyingDateTime = [date(2017, 4, 10)]
self.SellDateTime = [date(2018, 4, 16)]
self.BuyingDateTime.append(date(2017, 4, 10))
self.SellDateTime.append(date(2017, 7, 10))
self.NumberOfStocks = 10
self.PriceDiv = 'Open'
self.StockBuyingSearchTarget = ['Open']
self.StockSellSearchTarget = ['Open']
self.StockBuyingSearchTarget.append('Open')
self.StockSellSearchTarget.append('Open')
def doTrading(self):
return super().doTrading()
\ No newline at end of file
return super().doTrading()
......
from Investment.Verification.VerificationBase import VerificationBase
from datetime import date
class Verification(VerificationBase):
def __init__(self):
super().__init__
def __repr__(self):
return self.Name
......@@ -13,13 +12,15 @@ class Verification(VerificationBase):
super().setVerification()
def doVerification(self):
return super().doVerification()
return super().doVerification()
def saveResult(self):
return super().saveResult()
return super().saveResult()
def saveResulToJSON(self):
return super().saveResulToJSON()
return super().saveResulToJSON()
def saveSummary(self):
return super().saveSummary()
def saveSummary(self, record, num):
return super().saveSummary(record, num)
\ No newline at end of file
......
import Strategy
import Trading
import Verification
import sys
import DataProvider
st = Strategy.Strategy()
tr = Trading.Trading()
ve = Verification.Verification()
db = DataProvider.DataProvider()
if db.initialize():
print('db connection')
st.db = db
st.setStrategy()
if st.searchData() == False:
print("st.searchData error")
sys.exit(-1)
if st.setAdditionalData() == False:
print("st.setAdditionalData error")
sys.exit(-1)
tr.df_all = st.df_all
tr.db = db
tr.setTrading()
if tr.doTrading() == False:
print("tr.doTrading error")
sys.exit(-1)
ve.TotalInvestmentAmount = tr.TotalInvestmentAmount
ve.df_all = tr.df_all
ve.setVerification()
ve.doVerification()
ve.saveResult()
# ve.saveResulToJSON()
ve.saveSummary()
else:
print("db error")
db.close()
,StockCode,StockName,Equity,ProfitLoss,CashAndCashEquivalentsAtEndOfPeriodCf,Revenue,PER,MarketCapitalization,PBR,ROE,BuyingPrice,SellPrice,BuyingAmount,ProfitLossByStock,InvestmentAmount,Balance,Yield
0,084110,휴온스글로벌,453898247468.0,526207281324.0,91075668352.0,163712232478.0,0.48942596794175863,257539508000.0,0.5673948058549326,115.93067042214078,28050.0,37550.0,356.0,9500.0,9985800.0,13367800.0,33.8680926916221
1,032940,원익,123949666954.0,82550453825.0,1388965901.0,64804004293.0,0.8570857690254496,70752819200.0,0.5708189536826885,66.59998034172693,5570.0,7180.0,1795.0,1610.0,9998150.0,12888100.0,28.904847396768403
2,007860,서연,1072030023657.0,132366474007.0,291668735819.0,3188334589765.0,1.7827205413624674,235972432200.0,0.22011737264132844,12.347273032098506,10150.0,10250.0,985.0,100.0,9997750.0,10096250.0,0.9852216748768473
3,030530,원익홀딩스,722074414944.0,198963997320.0,31875697734.0,294905605408.0,2.352496789191469,468062164860.0,0.6482187364252482,27.55450036758753,6090.0,8040.0,1642.0,1950.0,9999780.0,13201680.0,32.01970443349754
4,023600,삼보판지,329937058742.0,40288485800.0,13938600553.0,326686709919.0,2.380332695452158,95900000000.0,0.29066149878904834,12.210961070458072,6860.0,6750.0,1457.0,-110.0,9995020.0,9834750.0,-1.6034985422740524
5,033160,엠케이전자,593852198159.0,74507668124.0,46704481994.0,619601002744.0,2.391281644105155,178168819130.0,0.30002215986122605,12.546500350589099,8360.0,10000.0,1196.0,1640.0,9998560.0,11960000.0,19.617224880382775
6,081660,휠라홀딩스,1302162825904.0,311126247136.0,149389365351.0,967128444713.0,2.8011166085227392,871500898200.0,0.6692718305753954,23.893037103098607,70400.0,78900.0,142.0,8500.0,9996800.0,11203800.0,12.073863636363637
7,037460,삼지전자,212713055001.0,38468337750.0,2657308940.0,1101581286777.0,2.9180729786017334,112253416920.0,0.5277222731791064,18.084615328297154,8130.0,8510.0,1230.0,380.0,9999900.0,10467300.0,4.674046740467404
8,005710,대원산업,221444272333.0,42811295063.0,108076996577.0,823571832855.0,2.9784663092381725,127512000000.0,0.575819815326955,19.332762420073752,7150.0,7110.0,1398.0,-40.0,9995700.0,9939780.0,-0.5594405594405595
9,122450,KMH,276591210392.0,35617262232.0,53301802111.0,159467610459.0,2.9847171536527886,106307453550.0,0.38434863276868175,12.877221290409516,7950.0,9400.0,1257.0,1450.0,9993150.0,11815800.0,18.238993710691823
10,,,,,,,,,,,,,,,,114775260.0,14.814649999999999
,StockCode,StockName,Equity,ProfitLoss,CashAndCashEquivalentsAtEndOfPeriodCf,Revenue,PER,MarketCapitalization,PBR,ROE,BuyingPrice,SellPrice,BuyingAmount,ProfitLossByStock,InvestmentAmount,Balance,Yield
0,084110,휴온스글로벌,453898247468.0,526207281324.0,91075668352.0,163712232478.0,0.48942596794175863,257539508000.0,0.5673948058549326,115.93067042214078,28050.0,37550.0,356.0,9500.0,9985800.0,13367800.0,33.8680926916221
1,032940,원익,123949666954.0,82550453825.0,1388965901.0,64804004293.0,0.8570857690254496,70752819200.0,0.5708189536826885,66.59998034172693,5570.0,7180.0,1795.0,1610.0,9998150.0,12888100.0,28.904847396768403
2,007860,서연,1072030023657.0,132366474007.0,291668735819.0,3188334589765.0,1.7827205413624674,235972432200.0,0.22011737264132844,12.347273032098506,10150.0,10250.0,985.0,100.0,9997750.0,10096250.0,0.9852216748768473
3,030530,원익홀딩스,722074414944.0,198963997320.0,31875697734.0,294905605408.0,2.352496789191469,468062164860.0,0.6482187364252482,27.55450036758753,6090.0,8040.0,1642.0,1950.0,9999780.0,13201680.0,32.01970443349754
4,023600,삼보판지,329937058742.0,40288485800.0,13938600553.0,326686709919.0,2.380332695452158,95900000000.0,0.29066149878904834,12.210961070458072,6860.0,6750.0,1457.0,-110.0,9995020.0,9834750.0,-1.6034985422740524
5,033160,엠케이전자,593852198159.0,74507668124.0,46704481994.0,619601002744.0,2.391281644105155,178168819130.0,0.30002215986122605,12.546500350589099,8360.0,10000.0,1196.0,1640.0,9998560.0,11960000.0,19.617224880382775
6,081660,휠라홀딩스,1302162825904.0,311126247136.0,149389365351.0,967128444713.0,2.8011166085227392,871500898200.0,0.6692718305753954,23.893037103098607,70400.0,78900.0,142.0,8500.0,9996800.0,11203800.0,12.073863636363637
7,037460,삼지전자,212713055001.0,38468337750.0,2657308940.0,1101581286777.0,2.9180729786017334,112253416920.0,0.5277222731791064,18.084615328297154,8130.0,8510.0,1230.0,380.0,9999900.0,10467300.0,4.674046740467404
8,005710,대원산업,221444272333.0,42811295063.0,108076996577.0,823571832855.0,2.9784663092381725,127512000000.0,0.575819815326955,19.332762420073752,7150.0,7110.0,1398.0,-40.0,9995700.0,9939780.0,-0.5594405594405595
9,122450,KMH,276591210392.0,35617262232.0,53301802111.0,159467610459.0,2.9847171536527886,106307453550.0,0.38434863276868175,12.877221290409516,7950.0,9400.0,1257.0,1450.0,9993150.0,11815800.0,18.238993710691823
10,,,,,,,,,,,,,,,,114775260.0,14.814649999999999
{
"TotalInvestmentAmount": "100000000",
"Balance": "103082220",
"Yield": "3.100435"
"Balance": "114775260",
"Yield": "14.814649999999999"
}
\ No newline at end of file
......