简体   繁体   中英

Python Optimization Moving Average

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM