I want to create moving average strategy with rolling funtion and scipy optimization but my code do not optimize rolling. It gives result which I entered as first x0 values. I searched for it in google there are ways to create all rolling possibilities but it takes lot of time. Is there any way to optimize efficiently. Here is my code, thanks in advance;
import pandas as pd
import os
import numpy as np
from datetime import datetime
import scipy.optimize as opt
#read file
data = pd.read_csv(r'C:\Users\Kaan\USDTRY-2018_06_01-2018_09_07.csv', encoding='utf-8', header=None, index_col=0)
data.columns = ['buy','sell',1,2]
data1 = data[['buy','sell']].head(100000)
# Optimization -------------------------------////////////////////------------------------------------
def objective(x):
x1 = x[0]
x2 = x[1]
x3 = x[2]
x4 = x[3]
data3 = pd.DataFrame(data=data1)
data3['sma1']=data3['buy'].rolling(int(x3)).mean()
data3['sma2']=data3['buy'].rolling(int(x4)).mean()
data3['sma1-sma2'] = np.round(data3['sma1']-data3['sma2'],5)
data3['pos'] = np.where(data3['sma1-sma2'] >= x1, 1, 0)
data3['pos'] = np.where((data3['sma1-sma2'] < -x1) ,-1, data3['pos'])
data3['pos'] = np.where(abs(data3['sma1-sma2']) > x2, 0, data3['pos'])
data3['return'] = np.round(np.log(data3['buy'] / data3['buy'].shift(1)),5)
data3['st'] = data3['pos'].shift(1)*data3['return']
return -1*data3['st'].cumsum().apply(np.exp).tail(1)[0]
def constraints1(x):
return x[3] * x[2] - 0
def constraints2(x):
return x[3] - x[2] - 0
b = (0.0,1000000.0)
bonds = (b,b,b,b)
x0=[0.00205062, 0.19746918, 893, 1990]
print(objective(x0))
con1 = {'type':'ineq','fun':constraints1}
con2 = {'type':'ineq','fun':constraints2}
cons = [con1,con2]
sol = opt.minimize(objective, x0, bounds=bonds, constraints=cons)
print(sol)
As an aside, it is normal in quant strategies to use EWMA as it preserves memory. If you want a super fast EWMA solution then see my other answer on calculating fast EWMA
As per the numba
examples this should significantly increase your code speed
import numpy as np
from numba import guvectorize
@guvectorize(['void(float64[:], intp[:], float64[:])'], '(n),()->(n)')
def move_mean(a, window_arr, out):
window_width = window_arr[0]
asum = 0.0
count = 0
for i in range(window_width):
asum += a[i]
count += 1
out[i] = asum / count
for i in range(window_width, len(a)):
asum += a[i] - a[i - window_width]
out[i] = asum / count
Another alternative is to replace guvectorize
with jit
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.