-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# pip install pandas | ||
|
||
import pandas as pd | ||
import os | ||
|
||
timeFrame = "D1" | ||
classCode = "TQBR" | ||
csv_folder_quik = "csv_quik" | ||
csv_folder_meta = "csv_meta" | ||
csv_folder_export = "csv_ok" | ||
|
||
if not os.path.exists(csv_folder_export): os.makedirs(csv_folder_export) | ||
|
||
# ok | ||
classSecurities = ['ABRD', 'ACKO', 'AFKS', 'AFLT', 'AGRO', 'AKRN', 'ALRS', 'AMEZ', 'APTK', 'AQUA', 'ARSA', 'ASSB', | ||
'AVAN', 'BANE', 'BANEP', 'BELU', 'BISVP', 'BLNG', 'BRZL', 'BSPB', 'BSPBP', 'CBOM', 'CHGZ', | ||
'CHKZ', 'CHMF', 'CHMK', 'CIAN', 'CNTL', 'CNTLP', 'DIOD', 'DSKY', 'DVEC', 'DZRD', 'DZRDP', 'EELT', | ||
'ELTZ', 'ENPG', 'ENRU', 'ETLN', 'FEES', 'FESH', 'FIVE', 'FIXP', 'FLOT', 'GAZA', 'GAZAP', 'GAZP', | ||
'GCHE', 'GEMA', 'GEMC', 'GLTR', 'GMKN', 'GTRK', 'HHRU', 'HIMCP', 'HMSG', 'HYDR', 'IGST', 'IGSTP', | ||
'INGR', 'IRAO', 'IRGZ', 'IRKT', 'ISKJ', 'JNOS', 'JNOSP', 'KAZT', 'KAZTP', 'KBSB', 'KCHE', | ||
'KCHEP', 'KGKC', 'KGKCP', 'KLSB', 'KMAZ', 'KMEZ', 'KOGK', 'KRKN', 'KRKNP', 'KRKOP', 'KROT', | ||
'KROTP', 'KRSB', 'KRSBP', 'KTSB', 'KTSBP', 'KUBE', 'KUZB', 'KZOS', 'KZOSP', 'LENT', 'LIFE', | ||
'LKOH', 'LNZL', 'LNZLP', 'LPSB', 'LSNG', 'LSNGP', 'LSRG', 'LVHK', 'MAGE', 'MAGEP', 'MAGN', | ||
'MDMG', 'MFGS', 'MFGSP', 'MGNT', 'MGNZ', 'MGTS', 'MGTSP', 'MISB', 'MISBP', 'MOEX', 'MRKC', | ||
'MRKK', 'MRKP', 'MRKS', 'MRKU', 'MRKV', 'MRKY', 'MRKZ', 'MRSB', 'MSNG', 'MSRS', 'MSTT', 'MTLR', | ||
'MTLRP', 'MTSS', 'MVID', 'NAUK', 'NFAZ', 'NKHP', 'NKNC', 'NKNCP', 'NKSH', 'NLMK', 'NMTP', 'NNSB', | ||
'NNSBP', 'NSVZ', 'NVTK', 'OGKB', 'OKEY', 'OMZZP', 'OZON', 'PAZA', 'PHOR', 'PIKK', 'PLZL', 'PMSB', | ||
'PMSBP', 'POGR', 'POLY', 'POSI', 'PRMB', 'QIWI', 'RASP', 'RAVN', 'RBCM', 'RDRB', 'RENI', 'RGSS', | ||
'RKKE', 'RNFT', 'ROLO', 'ROSB', 'ROSN', 'ROST', 'RSTI', 'RSTIP', 'RTGZ', 'RTKM', 'RTKMP', 'RTSB', | ||
'RTSBP', 'RUAL', 'RUGR', 'RUSI', 'RZSB', 'SAGO', 'SAGOP', 'SARE', 'SAREP', 'SBER', 'SBERP', | ||
'SELG', 'SFIN', 'SFTL', 'SGZH', 'SIBN', 'SLEN', 'SMLT', 'SNGS', 'SNGSP', 'SPBE', 'STSB', 'STSBP', | ||
'SVAV', 'SVET', 'TASB', 'TASBP', 'TATN', 'TATNP', 'TCSG', 'TGKA', 'TGKB', 'TGKBP', 'TGKD', | ||
'TGKDP', 'TGKN', 'TNSE', 'TORS', 'TORSP', 'TRMK', 'TRNFP', 'TTLK', 'TUZA', 'UCSS', 'UKUZ', | ||
'UNAC', 'UNKL', 'UPRO', 'URKZ', 'USBN', 'UTAR', 'VEON-RX', 'VGSB', 'VGSBP', 'VJGZ', 'VJGZP', | ||
'VKCO', 'VLHZ', 'VRSB', 'VRSBP', 'VSMO', 'VSYD', 'VSYDP', 'VTBR', 'WTCM', 'WTCMP', 'YAKG', | ||
'YKEN', 'YKENP', 'YNDX', 'YRSB', 'YRSBP', 'ZILL', 'ZVEZ'] | ||
|
||
# classSecurities = ['GAZP'] | ||
|
||
classSecurities_for_quik = [] | ||
classSecurities_for_meta = [] | ||
|
||
for secCode in classSecurities: | ||
file_quik = f'{csv_folder_quik}\\{classCode}.{secCode}_{timeFrame}.csv' | ||
file_meta = f'{csv_folder_meta}\\{classCode}.{secCode}_{timeFrame}.csv' | ||
file_export = f'{csv_folder_export}\\{classCode}.{secCode}_{timeFrame}.csv' | ||
|
||
isFileExists_quik = os.path.isfile(file_quik) # Существует ли файл | ||
if not isFileExists_quik: # Если файл не существует | ||
print(f'Файл {file_quik} не найден') | ||
|
||
isFileExists_meta = os.path.isfile(file_meta) # Существует ли файл | ||
if not isFileExists_meta: # Если файл не существует | ||
print(f'Файл {file_meta} не найден') | ||
|
||
try: | ||
df_quik = pd.read_csv(file_quik, sep=',') # Считываем файл в DataFrame | ||
df_meta = pd.read_csv(file_meta, sep=',') # Считываем файл в DataFrame | ||
df_quik["datetime"] = pd.to_datetime(df_quik["datetime"]) | ||
df_meta["datetime"] = pd.to_datetime(df_meta["datetime"]) | ||
#print(df_quik, df_meta, "\n----------------------------------------------------------------------------------------") | ||
|
||
date_quik = df_quik["datetime"][0] | ||
date_meta = df_meta["datetime"][0] | ||
if date_quik <= date_meta: | ||
classSecurities_for_quik.append(secCode) | ||
os.system(f"copy {file_quik} {file_export}") | ||
else: | ||
classSecurities_for_meta.append(secCode) | ||
os.system(f"copy {file_meta} {file_export}") | ||
print(f"ticker: {secCode}, quik: {date_quik}, meta: {date_meta}") | ||
|
||
except: | ||
print("Error with ticker: ", secCode) | ||
if isFileExists_quik: | ||
classSecurities_for_quik.append(secCode) | ||
os.system(f"copy {file_quik} {file_export}") | ||
if isFileExists_meta: | ||
classSecurities_for_meta.append(secCode) | ||
os.system(f"copy {file_meta} {file_export}") | ||
|
||
print(f"Total tickers from quik: {len(classSecurities_for_quik)}", classSecurities_for_quik) | ||
print(f"Total tickers from meta: {len(classSecurities_for_meta)}", classSecurities_for_meta) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import pandas as pd | ||
import datetime | ||
import webbrowser | ||
import backtrader as bt | ||
import quantstats as qs | ||
import yfinance as yf | ||
|
||
class SmaCross(bt.SignalStrategy): | ||
params = dict( | ||
pfast=50, # период быстрой средней, 50 свечей | ||
pslow=200 # 200 свечей для медленной средней | ||
) | ||
|
||
def __init__(self): | ||
sma1, sma2 = bt.ind.SMA(period=self.p.pfast), bt.ind.SMA(period=self.p.pslow) # используем простые скользящие средние | ||
self.crossover = bt.ind.CrossOver(sma1, sma2) | ||
|
||
def next(self): | ||
if not self.position: # если позиция не открыта системой | ||
if self.crossover > 0: # если быстрая SMA пересекает медленную вверх | ||
self.buy() # открываем длинную позицию | ||
|
||
elif self.crossover < 0: # во всех остальных случаях закрываем открытую позицию | ||
self.close() | ||
|
||
# data = bt.feeds.PandasData(dataname=yf.download('MSFT', '2007-02-02', '2021-09-01', auto_adjust=True)) # в качестве примера берём MSFT, 2008 год тоже торгуем | ||
|
||
data = pd.read_csv("csv\\TQBR.GAZP_D1.csv", sep=',') #, index_col='datetime') | ||
# data.index = pd.to_datetime(data.index, format='%Y-%m-%d %H:%M') | ||
print(data) | ||
print(data.dtypes) | ||
|
||
# data = data.reset_index() | ||
# print(data) | ||
data.rename(columns={'datetime': 'Date', 'open': 'Open', 'high': 'High', | ||
'low': 'Low', 'close': 'Close', 'volume': 'Volume'}, | ||
inplace=True) # Чтобы получить дату/время переименовываем колонки | ||
|
||
data['Date'] = pd.to_datetime(data['Date']) | ||
data = data.set_index('Date') | ||
|
||
# data.index = data['Date'] | ||
# data = data.drop('Date', 1) | ||
|
||
# data = yf.download('MSFT', '2007-02-02', '2021-09-01', auto_adjust=True) | ||
|
||
print(data) | ||
print(data.dtypes) | ||
print(data.index.dtype) | ||
|
||
data = bt.feeds.PandasData(dataname=data) # в качестве примера берём MSFT, 2008 год тоже торгуем | ||
|
||
cerebro = bt.Cerebro() | ||
cerebro.broker.setcash(1000000) # начальный депозит 10 000 денег | ||
cerebro.addsizer(bt.sizers.FixedSize, stake=10) # размер позиции 10 лотов | ||
cerebro.adddata(data) | ||
cerebro.addstrategy(SmaCross) | ||
cerebro.addanalyzer(bt.analyzers.PyFolio, _name='PyFolio') # PyFolio, но quantstats его тоже отрендерит | ||
results = cerebro.run() | ||
|
||
#cerebro.plot() | ||
|
||
strat = results[0] | ||
portfolio_stats = strat.analyzers.getbyname('PyFolio') | ||
returns, positions, transactions, gross_lev = portfolio_stats.get_pf_items() | ||
returns.index = returns.index.tz_convert(None) | ||
|
||
print(returns) | ||
|
||
qs.reports.html(returns, 'GAZP.ME', output='stats.html', title='SMA Cross') # формируем репорт в quantstats, вместо бенчмарка SPY используем buy&hold MSFT | ||
# webbrowser.open('quantstats-tearsheet.html') # рендерим репорт в html и открываем в новой вкладке |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import datetime | ||
import webbrowser | ||
import backtrader as bt | ||
import quantstats as qs | ||
import yfinance as yf | ||
|
||
class SmaCross(bt.SignalStrategy): | ||
params = dict( | ||
pfast=50, # период быстрой средней, 50 свечей | ||
pslow=200 # 200 свечей для медленной средней | ||
) | ||
|
||
def __init__(self): | ||
sma1, sma2 = bt.ind.SMA(period=self.p.pfast), bt.ind.SMA(period=self.p.pslow) # используем простые скользящие средние | ||
self.crossover = bt.ind.CrossOver(sma1, sma2) | ||
|
||
def next(self): | ||
if not self.position: # если позиция не открыта системой | ||
if self.crossover > 0: # если быстрая SMA пересекает медленную вверх | ||
self.buy() # открываем длинную позицию | ||
|
||
elif self.crossover < 0: # во всех остальных случаях закрываем открытую позицию | ||
self.close() | ||
|
||
data = yf.download('MSFT', '2007-02-02', '2021-09-01', auto_adjust=True) | ||
print(data) | ||
print(data.dtypes) | ||
print(data.index.dtype) | ||
|
||
data = bt.feeds.PandasData(dataname=data) # в качестве примера берём MSFT, 2008 год тоже торгуем | ||
|
||
cerebro = bt.Cerebro() | ||
cerebro.broker.setcash(10000) # начальный депозит 10 000 денег | ||
cerebro.addsizer(bt.sizers.FixedSize,stake = 100) # размер позиции 100 лотов | ||
cerebro.adddata(data) | ||
cerebro.addstrategy(SmaCross) | ||
cerebro.addanalyzer(bt.analyzers.PyFolio, _name='PyFolio') # PyFolio, но quantstats его тоже отрендерит | ||
results = cerebro.run() | ||
|
||
# cerebro.plot() | ||
|
||
strat = results[0] | ||
portfolio_stats = strat.analyzers.getbyname('PyFolio') | ||
returns, positions, transactions, gross_lev = portfolio_stats.get_pf_items() | ||
returns.index = returns.index.tz_convert(None) | ||
|
||
print(returns) | ||
|
||
qs.reports.html(returns, 'MSFT', output='stats.html', title='SMA Cross') # формируем репорт в quantstats, вместо бенчмарка SPY используем buy&hold MSFT | ||
# webbrowser.open('quantstats-tearsheet.html') # рендерим репорт в html и открываем в новой вкладке |