【问题标题】:how to multiple variables in for loop range python如何在for循环范围python中使用多个变量
【发布时间】:2021-08-02 11:34:07
【问题描述】:

我似乎无法让以下 for 循环在范围内工作。这是整个代码。或许贴出整个程序更有帮助

import pandas as pd
from alpha_vantage.timeseries import TimeSeries
from alpha_vantage.foreignexchange import ForeignExchange
from scipy.stats import ttest_ind
from pandas import ExcelWriter
import time
import numpy as np
import os

api_key="xxx"

cc = ForeignExchange(key=api_key, output_format="pandas", indexing_type= "date")
#ti = TechIndicators(key= api_key, output_format="pandas", indexing_type= "date")
ts = TimeSeries(key= api_key, output_format="pandas", indexing_type= "date")

filePath = r"/Users/LaCasa/PycharmProjects/Forex_Breakout_Backtest_15MIN/forex_pairs.xlsx"
filePath1 = r"/Users/LaCasa/PycharmProjects/Forex_Breakout_Backtest_15MIN/"
stocklist = pd.read_excel(filePath, engine='openpyxl')
stocklist = stocklist.head(5)

exportList = pd.DataFrame(columns=['Base','Quote'])

for i in stocklist.index:
    fx_from = str(stocklist["fx_from"][i])
    fx_to = str(stocklist["fx_to"][i])
    data_fx, meta_data_fx = cc.get_currency_exchange_intraday(from_symbol=fx_from,to_symbol=fx_to,interval='15min',
                                                              outputsize='full')
    data_fx.sort_index(inplace=True)

    total_df = data_fx
    total_df["BASE"] = fx_from
    total_df["QUOTE"] = fx_to
    total_df.rename(columns={'1. open': 'OPEN','2. high': 'HIGH','3. low': 'LOW','4. close':'CLOSE'},inplace=True)

    result = []
    train_size = 0.6
    n_forward = 5

    total_df['Forward Close'] = total_df['CLOSE'].shift(-n_forward)
    total_df['Forward Return'] = (total_df['Forward Close'] - total_df['CLOSE']) / total_df['CLOSE']

    for sma_length, sma_length2, sma_length3 in range(10, 200, 10):
        print(sma_length)
        total_df["MA1"] = round(total_df["CLOSE"].rolling(window=sma_length).mean(), 5)
        total_df["SD1"] = round(total_df["CLOSE"].rolling(window=sma_length).std(), 5)
        total_df["z1"] = round((total_df["CLOSE"].sub(total_df["MA1"])).div(total_df["SD1"]), 3)
        total_df["Z1"] = round(total_df["z1"].rolling(window=1).mean(), 3)
        total_df["MAZ1"] = round(total_df["Z1"].rolling(window=3).mean(), 5)
        total_df["SDMA1"] = round(total_df["SD1"].rolling(window=sma_length).mean(), 5)
        total_df["STD1"] = round(total_df["SD1"].rolling(window=sma_length).std(), 5)
        total_df["zd1"] = round((total_df["SD1"].sub(total_df["SDMA1"])).div(total_df["STD1"]), 3)
        total_df["ZDEV1"] = round(total_df["zd1"].rolling(window=1).mean(), 3)
        total_df["MAZDEV1"] = round(total_df["ZDEV1"].rolling(window=3).mean(), 3)

        total_df["MA2"] = round(total_df["CLOSE"].rolling(window=sma_length2).mean(), 5)
        total_df["SD2"] = round(total_df["CLOSE"].rolling(window=sma_length2).std(), 5)
        total_df["z2"] = round((total_df["CLOSE"].sub(total_df["MA2"])).div(total_df["SD2"]), 3)
        total_df["Z2"] = round(total_df["z2"].rolling(window=1).mean(), 3)
        total_df["MAZ2"] = round(total_df["Z2"].rolling(window=3).mean(), 5)
        total_df["SDMA2"] = round(total_df["SD2"].rolling(window=sma_length2).mean(), 5)
        total_df["STD2"] = round(total_df["SD2"].rolling(window=sma_length2).std(), 5)
        total_df["zd2"] = round((total_df["SD2"].sub(total_df["SDMA2"])).div(total_df["STD2"]), 3)
        total_df["ZDEV2"] = round(total_df["zd2"].rolling(window=1).mean(), 3)
        total_df["MAZDEV2"] = round(total_df["ZDEV2"].rolling(window=3).mean(), 3)

        total_df["MA3"] = round(total_df["CLOSE"].rolling(window=sma_length3).mean(), 5)
        total_df["SD3"] = round(total_df["CLOSE"].rolling(window=sma_length3).std(), 5)
        total_df["z3"] = round((total_df["CLOSE"].sub(total_df["MA3"])).div(total_df["SD3"]), 3)
        total_df["Z3"] = round(total_df["z3"].rolling(window=1).mean(), 3)
        total_df["MAZ3"] = round(total_df["Z3"].rolling(window=3).mean(), 5)
        total_df["SDMA3"] = round(total_df["SD3"].rolling(window=sma_length3).mean(), 5)
        total_df["STD3"] = round(total_df["SD3"].rolling(window=sma_length3).std(), 5)
        total_df["zd3"] = round((total_df["SD3"].sub(total_df["SDMA3"])).div(total_df["STD3"]), 3)
        total_df["ZDEV3"] = round(total_df["zd3"].rolling(window=1).mean(), 3)
        total_df["MAZDEV3"] = round(total_df["ZDEV3"].rolling(window=3).mean(), 3)

        # BREAKOUT
        total_df['input1'] = [int(x) for x in total_df['Z1'] > 2]
        total_df['input2'] = [int(x) for x in total_df['Z1'].shift(1) < 2]

        # VOLATILITY
        total_df['input3'] = [int(x) for x in (total_df['ZDEV2'] > total_df['MAZDEV2'])]

        #total_df = total_df.dropna(subset=["MAZDEV2"], inplace=False)

        #VOLATILITY #2
        total_df['input4'] = [int(x) for x in (total_df['ZDEV3'] > total_df['MAZDEV3'])]
        total_df['input5'] = [int(x) for x in total_df['ZDEV3'] < 1]
        #
        # #TREND
        total_df['input6'] = [int(x) for x in (total_df['Z3'] > total_df['MAZ3'])]
        #total_df['input7'] = [int(x) for x in total_df['Z3'] > 1]
        print(total_df['input4'])
        training = total_df.head(int(train_size * total_df.shape[0]))
        test = total_df.tail(int((1 - train_size) * total_df.shape[0]))

        tr_returns = training[training['input1' and 'input2' and 'input3' and 'input4' and 'input5' and 'input6'] == 1]['Forward Return']
        test_returns = test[test['input1' and 'input2' and 'input3' and 'input4' and 'input5' and 'input6'] == 1]['Forward Return']

        mean_forward_return_training = tr_returns.mean()
        mean_forward_return_test = test_returns.mean()

        pvalue = ttest_ind(tr_returns, test_returns, equal_var=False)[1]
        result.append({
            'base': fx_from,
            'quote': fx_to,
            'sma_length': sma_length,
            'sma_length2': sma_length2,
            'sma_length3': sma_length3,
            'training_forward_return': mean_forward_return_training,
            'test_forward_return': mean_forward_return_test,
            'p-value': pvalue
        })

    result.sort(key=lambda x: -x['training_forward_return'])
    print(result[0])
    time.sleep(15)
    newFile = os.path.dirname(filePath1) + "/period.xlsx"
    writer = ExcelWriter(newFile)
    total_df.to_excel(writer, "Sheet1", float_format="%.7f")
    writer.save()

错误:TypeError:无法解压不可迭代的 int 对象

理想情况下,我喜欢为您在上面看到的每个 ZScore 公式找到最佳滚动窗口,但不知道如何使循环工作

【问题讨论】:

  • 您希望在循环变量中看到什么值? in range(20,500) 每次迭代都会给你一个int,你不能解压。
  • range() 在每个循环中生成单个值 - 您必须使用 for value in range(20, 500)。
  • 您想尝试此范围内 3 个值的所有可能组合吗?如果是这种情况,您可以查看 itertools.product - 但请注意,组合将超过 1.11 亿。
  • range(20, 500) 返回如下序列:[20, 21, 22, ..., 500]。所以每次迭代你一次得到一个整数,它不能被解压缩成一个 3 元组(sma_* 变量)。这正是错误消息所说的。这相当于:x, y, z = 1。
  • 老实说,这实际上让我们很难清楚地看到所有这些。你想为你的 3 个 sma 长度获得什么值?

标签: python pandas dataframe for-loop


【解决方案1】:

正如错误所说,您正在尝试将单个整数解压缩为 3 个值。

迭代器range(20, 500) 在每次迭代时只返回一个整数。

for i in range(20, 50):
   do_something(i)
   do_something_else(i)
   do_a_third_thing(i)

# i is the same single integer in each case

除此之外,我不确定您要做什么。如果您需要 3 个不同的值,则可以使用具有 3 个不同值的迭代器。你可以这样做:

for i, j, k in [(a1, b1, c1), (a2, b2, c2), ...]:
    ...

但必须有三个值才能“解包”。

编辑: 据我从您的脚本中可以看出,您可以尝试两件事...

也许完全删除 sma_length2 和 sma_length3 变量,因为 for 循环的本质是它会遍历给定的值,因此您将获得您定义的范围内的所有结果。

类似这样的:

for sma_length in range(10, 201):      # remember that with the iterable returned from range, the last value will not be included.
        print(sma_length)
        total_df["MA1"] = round(total_df["CLOSE"].rolling(window=sma_length).mean(), 5)
        total_df["SD1"] = round(total_df["CLOSE"].rolling(window=sma_length).std(), 5)
        total_df["z1"] = round((total_df["CLOSE"].sub(total_df["MA1"])).div(total_df["SD1"]), 3)
        total_df["Z1"] = round(total_df["z1"].rolling(window=1).mean(), 3)
        total_df["MAZ1"] = round(total_df["Z1"].rolling(window=3).mean(), 5)
        total_df["SDMA1"] = round(total_df["SD1"].rolling(window=sma_length).mean(), 5)
        total_df["STD1"] = round(total_df["SD1"].rolling(window=sma_length).std(), 5)
        total_df["zd1"] = round((total_df["SD1"].sub(total_df["SDMA1"])).div(total_df["STD1"]), 3)
        total_df["ZDEV1"] = round(total_df["zd1"].rolling(window=1).mean(), 3)
        total_df["MAZDEV1"] = round(total_df["ZDEV1"].rolling(window=3).mean(), 3)

由于您使用此循环测试所有介于 10 和 200 之间的值,我不确定您为什么需要其他 2 个 sma_length 变量。

关于上面的代码需要单独注意的一点是,您有一些“幻数”,在每次迭代中都是相同的。

例如,当您编写“window=3”或“window=1”时,这将永远不会改变,您只是在浪费地为每个循环重新计算相同的值。

但是,如果您实际上同时需要 3 个不同的 sma_length,您可以使用 zip() 内置函数来创建如上所述的可迭代对象(长度为 3 的元组序列)。

你可以这样做:

iterable = zip(range(100), range(100, 200), range(200, 300))

for a, b, c in iterable:
    print((a, b, c))

# (0, 100, 200)
# (1, 101, 201)
# (2, 102, 202)
# ... etc. 

但正如我所说,我认为您可以像上一个示例中那样只使用一个变量来完成您需要的操作。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-30
    • 2014-08-05
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    相关资源
    最近更新 更多