# ETF定投数据分析7——模拟交易系统开发

# -*- coding:utf-8 -*-
# 模拟交易程序

class simulate(object):
def __init__(self, totalTimes):
self.totalTimes = totalTimes
pass

# 计算持仓股票市值
def getValue(self):
pass

# 判断是否进行止盈操作
def isStopProfit(self):
pass

# 进行止盈操作
def doStopProfit(self):
pass

# 进行交易
pass

# 判断是否需要重新购买
pass

# 用止盈的钱重新购买etf
pass

# 更新相关数据
def updateData(self):
pass

#计算回测指标
def getIndex(self):
pass

# 执行交易循环
def run(self):
self.getValue()
if self.isStopProfit():
self.doStopProfit()
else:
else:
self.updateData()
self.getIndex()

if __name__ == "__main__":
test = simulate(10)
test.run()


# 执行交易循环
def run(self):
for days in range(self.totalTimes):
if days % self.freq == 0: #进行交易
else:
for code in range(2):
self.update(code, days)
# print("位置a", days, self.value[0][days], self.cost[0][days], self.rate[0][days], self.value[1][days], self.cost[1][days], self.rate[1][days], self.totalrate[days])
if days == 0:
self.minPrice[0] = self.data[0]["close"][0]
self.minPrice[1] = self.data[1]["close"][0]
self.maxPrice[0] = self.data[0]["close"][0]
self.maxPrice[1] = self.data[1]["close"][0]
else:
for code in range(2):
if self.isStopProfit(code, days):
self.doStopProfit(code, days)
# print(code, days, "止盈")
# print(code, days, self.cost[code][days-1], self.value[code][days-1], self.cost[code][days], self.value[code][days])

for code in range(2):
# print(code, days, "停止止盈")
# print(code, days, self.cost[code][days-1], self.value[code][days-1], self.cost[code][days], self.value[code][days])

# # 止盈后更新数据
# for code in range(2):
#     self.cutUpdate(code, days)
self.combine(days)
# print("位置b", days, self.value[0][days], self.cost[0][days], self.rate[0][days], self.value[1][days], self.cost[1][days], self.rate[1][days], self.totalrate[days])
# print(days, self.totalcost[days], self.totalvalue[days], self.totalrate[days])
self.getIndex()
# 作图测试
plt.figure()
plt.plot(self.rate[0], label = "300etf", linestyle = "-")
plt.plot(self.data[0]["close"]/self.data[0]["close"][0]-1.0, label = "300", linestyle = "-.")
plt.legend(loc="best")
# plt.show()
plt.savefig("simulate_01.png")
plt.figure()
plt.plot(self.rate[1], label = "nasetf", linestyle = "--")
plt.plot(self.data[1]["close"]/self.data[1]["close"][0]-1.0, label = "nas", linestyle = ":")
plt.legend(loc="best")
# plt.show()
plt.savefig("simulate_02.png")
plt.figure()
plt.plot(self.data[0]["close"]/self.data[0]["close"][0]-1.0, label = "300", linestyle = "-.")
plt.plot(self.data[1]["close"]/self.data[1]["close"][0]-1.0, label = "nas", linestyle = ":")
plt.plot(self.totalrate, label = "total")
plt.legend(loc="best")
# plt.show()
plt.savefig("simulate_03.png")

plt.figure()

plt.plot(self.value[0], label = "300value")
plt.plot(self.cost[0], label = "300cost")
plt.legend(loc = "best")
plt.savefig("debug1.png")

plt.figure()

plt.plot(self.value[1], label = "nasvalue")
plt.plot(self.cost[1], label = "nascost")
plt.legend(loc = "best")
plt.savefig("debug2.png")


# 判断是否进行止盈操作，根据days前的交易情况，code为0或1
def isStopProfit(self, code, days):
# return False # 测试用
price = self.data[code]["close"][days]
# 没有正在进行止盈
if self.bStop[code] == False:
if self.minPrice[code] > price:
self.minPrice[code] = price
if self.maxPrice[code] < price:
self.maxPrice[code] = price
# 判断止盈条件
if price/self.maxPrice[code] <= 1.0 - self.stopPoint:
self.bStop[code] = True
# 将最高/低价调整到现价
self.maxPrice[code] = price
self.minPrice[code] = price
return True
# 如果已经进行了止盈
if self.bStop[code] == True:
if self.minPrice[code] > price:
self.minPrice[code] = price
# 判断止盈条件
if price/self.maxPrice[code] <= 1.0 - self.stopPoint:
# 将最高/低价调整到现价
self.maxPrice[code] = price
self.minPrice[code] = price
return True
return False

# 进行止盈操作
def doStopProfit(self, code, days):
money = self.value[code][days-1]/2.0
value = num * self.data[code]["close"][days]
fee = self.getFee(num, self.data[code]["close"][days])
# 更新数据
# 只有股票数量大于一手并且交易金额小于预定金额才做
if num > 100 and value + fee <= money:
# print("止盈前", code, days, self.value[code][days], self.cost[code][days], self.stock[code][days], self.rate[code][days], num, value, fee)
self.money_cut[code] += value - fee

# print("a", code, days, money, num, value, fee)
# 进行止盈操作
self.stock[code][days] -= num
self.value[code][days] -= value
self.fee[code][days] += fee
self.rate[code][days] = (self.value[code][days] + self.money_cut[code])/ self.cost[code][days] -1.0
#self.cutValue[code] = value
#            self.cutFee[code] = fee
# print(self.cost[code])
# print(self.value[code])
# print(self.rate[code])
# print("止盈后", code, days, self.value[code][days], self.cost[code][days], self.stock[code][days], self.rate[code][days], num, value, fee)
else:
self.bStop[code] = False

# 判断是否需要重新购买
# return False #测试用
# 如果进行了止盈，判断是否停止止盈
if self.bStop[code] == True or self.bStart[code] == True:
price = self.data[code]["close"][days]
if price/self.minPrice[code] >= 1.0 + self.startPoint:
self.bStart[code] = True
# 将最高/低价调整到现价
self.maxPrice[code] = price
self.minPrice[code] = price
# 停止止盈
self.bStop[code] = False
return True
return False

# 用止盈的钱重新购买etf
# 用止盈得到的剩余的钱的一半以现价再投资。
money = self.money_cut[code]/2.0
value = num * self.data[code]["close"][days]
fee = self.getFee(num, self.data[code]["close"][days])
# print("止盈", code, days, money, num, value, fee)
# 如果可以交易的股票数量低于一手，或者股价+手续费大于预定的金额，则停止交易。
if num <= 100 or value + fee > money:
self.bStart[code] = False
else: # 进行交易并更新数据。
# print("停止止盈前", code, days, self.value[code][days], self.cost[code][days], self.stock[code][days], self.rate[code][days], num, value, fee)
self.stock[code][days] += num
self.value[code][days] += value
self.fee[code][days] += fee
self.money_cut[code] -= value+fee
# print("停止止盈后", code, days, self.value[code][days], self.cost[code][days], self.stock[code][days], self.rate[code][days], num, value, fee)