【发布时间】:2017-02-02 01:58:00
【问题描述】:
NB 如果复制我的代码会运行
我编写了一个简单的脚本来使用 poloniex API 回测加密货币。
首先我从 API 请求数据并将其转换为数据帧data。
然后我获取我想要的数据并创建名为df的新df
然后必须在df 的每一行上运行一个函数trade,简单地说,如果价格高于滚动平均值,则它会买入和卖出,如果低于,则此数据将保存在log。
我无法在df 的每一行上应用此函数。
我使用log = df.apply(lambda x: trade(x['date'], x['close'], x['MA']), axis=1) 行取得了巨大成功,但令人惊讶的是,它在 API 调用中使用 BTC_ETH 时有效,而不是用于其他人,即 BTC_FCT 或 BTC_DOGE,尽管数据形式相同。使用 ETH 会导致创建 DataFrame(这是我想要的)DOGE 和 FCT 创建一个系列
第一个问题,我如何在每一行上运行我的 trade 函数并使用结果创建一个新的 df log
额外问题,即使数据类型相同,为什么它适用于 ETH 而不适用于 DOGE/FCT?
import numpy as np
from pandas import Series, DataFrame
import pandas as pd
API = 'https://poloniex.com/public?command=returnChartData¤cyPair=BTC_FCT&start=1435699200&end=9999999999&period=86400'
data = pd.read_json(API)
df = pd.DataFrame(columns = {'date','close','MA'})
df.MA = pd.rolling_mean(data.close, 30)
df.close = data.close
df.date = data.date
df = df.truncate(before=29)
def print_full(x):
pd.set_option('display.max_rows', len(x))
print(x)
pd.reset_option('display.max_rows')
log = pd.DataFrame(columns = ['Date', 'type', 'profit', 'port_value'])
port = {'coin': 0, 'BTC':1}
def trade(date, close, MA):
if MA < close and port['coin'] == 0 :
coins_bought = port['BTC']/MA
port['BTC'] = 0
port['coin'] = coins_bought
d = {'Date':date, 'type':'buy', 'coin_value': port['coin'], 'btc_value':port['BTC']}
return pd.Series(d)
elif MA > close and port['BTC'] == 0 :
coins_sold = port['coin']*MA
port['coin'] = 0
port['BTC'] = coins_sold
d = {'Date':date, 'type':'sell', 'coin_value': port['coin'], 'btc_value':port['BTC']}
print()
return pd.Series(d)
log = df.apply(lambda x: trade(x['date'], x['close'], x['MA']), axis=1)
log = log.dropna()
print_full(log)
编辑:
我解决了这个问题,我通过将字典附加到列表然后使用 df.from_dict() 方法来创建日志数据框来修复它,我的代码只是为了澄清。
def trade(date, close, MA):#, port):
#d = {'Data': close}
#test_log = test_log.append(d, ignore_index=True)
if MA < close and port['coin'] == 0 :
coins_bought = port['BTC']/MA
port['BTC'] = 0
port['coin'] = coins_bought
d = {'Date':date, 'type':'buy', 'coin_value': port['coin'], 'btc_value':port['BTC']}
data_list.append(d)
#return pd.Series(d)
elif MA > close and port['BTC'] == 0 :
coins_sold = port['coin']*MA
port['coin'] = 0
port['BTC'] = coins_sold
d = {'Date':date, 'type':'sell', 'coin_value': port['coin'], 'btc_value':port['BTC']}
data_list.append(d)
#return pd.Series(d)
df.apply(lambda x: trade(x['date'], x['close'], x['MA']), axis=1)
log = log.dropna()
for key,value in port.items():
print(key, value )
log.from_dict(data_list)
【问题讨论】:
-
根据the documentation of
apply,使用具有副作用的函数(如您的)可能会导致意外行为,因为第一行调用了两次(参见“注释”)。
标签: python pandas numpy dataframe