Type/to search
8
Follow
1376
Followers
Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line
Original
Created 2019-12-21 09:38:26  Updated 2024-12-15 15:59:54
 4
 3391

img

Je vous apprends étape par étape à écrire une version Python de la fonction de synthèse K-line

Lors de la rédaction et de l'utilisation de stratégies, certaines données de cycle K-line peu courantes sont souvent utilisées. Cependant, les échanges et les sources de données ne fournissent pas de données pour ces périodes. Elle ne peut être synthétisée qu’en utilisant des données provenant de cycles existants. L'algorithme de synthèse possède déjà une version JavaScript (Lien), en fait, il est très simple de porter un code JavaScript vers la version Python. Ensuite, écrivons une version Python de l’algorithme de synthèse K-line.

Version JavaScript

function GetNewCycleRecords (sourceRecords, targetCycle) { // K线合成函数 var ret = [] // 首先获取源K线数据的周期 if (!sourceRecords || sourceRecords.length < 2) { return null } var sourceLen = sourceRecords.length var sourceCycle = sourceRecords[sourceLen - 1].Time - sourceRecords[sourceLen - 2].Time if (targetCycle % sourceCycle != 0) { Log("targetCycle:", targetCycle) Log("sourceCycle:", sourceCycle) throw "targetCycle is not an integral multiple of sourceCycle." } if ((1000 * 60 * 60) % targetCycle != 0 && (1000 * 60 * 60 * 24) % targetCycle != 0) { Log("targetCycle:", targetCycle) Log("sourceCycle:", sourceCycle) Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle) throw "targetCycle cannot complete the cycle." } var multiple = targetCycle / sourceCycle var isBegin = false var count = 0 var high = 0 var low = 0 var open = 0 var close = 0 var time = 0 var vol = 0 for (var i = 0 ; i < sourceLen ; i++) { // 获取 时区偏移数值 var d = new Date() var n = d.getTimezoneOffset() if (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) { isBegin = true } if (isBegin) { if (count == 0) { high = sourceRecords[i].High low = sourceRecords[i].Low open = sourceRecords[i].Open close = sourceRecords[i].Close time = sourceRecords[i].Time vol = sourceRecords[i].Volume count++ } else if (count < multiple) { high = Math.max(high, sourceRecords[i].High) low = Math.min(low, sourceRecords[i].Low) close = sourceRecords[i].Close vol += sourceRecords[i].Volume count++ } if (count == multiple || i == sourceLen - 1) { ret.push({ High : high, Low : low, Open : open, Close : close, Time : time, Volume : vol, }) count = 0 } } } return ret }

S'il existe un algorithme JavaScript, il peut être traduit et transplanté en Python ligne par ligne. Lorsque vous rencontrez des fonctions intégrées ou des méthodes inhérentes à JavaScript, recherchez simplement les méthodes correspondantes dans Python, la transplantation est donc relativement facile.
La logique de l'algorithme est exactement la même, juste l'appel de fonction JavaScriptvar n = d.getTimezoneOffset()Lors du portage vers Python, utilisez la bibliothèque temporelle de Pythonn = time.altzoneremplacer. D'autres différences résident uniquement dans la syntaxe du langage (comme l'utilisation de boucles for, les différences dans les valeurs booléennes, les différences dans l'utilisation de "et" logique, "non" logique, "ou" logique, etc.).

Le code Python transplanté :

import time def GetNewCycleRecords(sourceRecords, targetCycle): ret = [] # 首先获取源K线数据的周期 if not sourceRecords or len(sourceRecords) < 2 : return None sourceLen = len(sourceRecords) sourceCycle = sourceRecords[-1]["Time"] - sourceRecords[-2]["Time"] if targetCycle % sourceCycle != 0 : Log("targetCycle:", targetCycle) Log("sourceCycle:", sourceCycle) raise "targetCycle is not an integral multiple of sourceCycle." if (1000 * 60 * 60) % targetCycle != 0 and (1000 * 60 * 60 * 24) % targetCycle != 0 : Log("targetCycle:", targetCycle) Log("sourceCycle:", sourceCycle) Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle) raise "targetCycle cannot complete the cycle." multiple = targetCycle / sourceCycle isBegin = False count = 0 barHigh = 0 barLow = 0 barOpen = 0 barClose = 0 barTime = 0 barVol = 0 for i in range(sourceLen) : # 获取时区偏移数值 n = time.altzone if ((1000 * 60 * 60 * 24) - (sourceRecords[i]["Time"] * 1000) % (1000 * 60 * 60 * 24) + (n * 1000)) % targetCycle == 0 : isBegin = True if isBegin : if count == 0 : barHigh = sourceRecords[i]["High"] barLow = sourceRecords[i]["Low"] barOpen = sourceRecords[i]["Open"] barClose = sourceRecords[i]["Close"] barTime = sourceRecords[i]["Time"] barVol = sourceRecords[i]["Volume"] count += 1 elif count < multiple : barHigh = max(barHigh, sourceRecords[i]["High"]) barLow = min(barLow, sourceRecords[i]["Low"]) barClose = sourceRecords[i]["Close"] barVol += sourceRecords[i]["Volume"] count += 1 if count == multiple or i == sourceLen - 1 : ret.append({ "High" : barHigh, "Low" : barLow, "Open" : barOpen, "Close" : barClose, "Time" : barTime, "Volume" : barVol, }) count = 0 return ret # 测试 def main(): while True: r = exchange.GetRecords() r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4) ext.PlotRecords(r2, "r2") Sleep(1000)

test

Graphique du marché Huobi
img

Backtesting du graphique synthétique sur 4 heures
img

Le code ci-dessus n'est utilisé qu'à titre de référence d'apprentissage. S'il est utilisé dans une stratégie spécifique, veuillez le modifier et le tester en fonction de vos besoins.
Si vous avez des BUG ou des suggestions d'amélioration, veuillez laisser un message, merci beaucoup o^_^o

Related Recommendations
Comment
All comments (4)

    img 啊哈 ,梦梦老师技术比我高。截图给梦梦老师参考。

    7 years ago

    赞,我Python 不行,只是初学。

    7 years ago

    py 用resample函数 一行搞定了。

    7 years ago

    666 学习下。

    7 years ago
  • 1
Forums
PINE Language
Get the app
iPhone Download
© 2015 - ∞ INVENTOR PTE LTD (SG)