solana 開発勉強日誌３ OrcaClammBot

開発勉強日誌が行き詰まり（solana難しい）

とりあえずsolanaでbot的なやつ動かしたい
自分のモチベを維持する為に！！！
という事で見つけてきたのは

https://github.com/regonn/OrcaClammBot

https://zenn.dev/regonn/articles/orca-clamm-bot-01#wallet-%E3%81%AB%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%A8-solana-%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B


とても良さそう。面白そう
```
git clone https://github.com/regonn/OrcaClammBot.git
```
```
cd OrcaClammBot
```

https://www.hellomoon.io/dashboard



上記でhello moon のAPIを取得

```.env.sampleをコピーして.envを生成.
HELLO_MOON_API_KEY=14d0000-ab00-0000-a0a0-000000000
ANCHOR_PROVIDER_URL=https://api.mainnet-beta.solana.com
ANCHOR_WALLET=inu_neko.json
```
```依存関係のインストール.
npm install
npm install @hellomoon/api
```

999-functions.tsのファイルが
import secret from "./wallet.json";
上記になっていたのでwallet.jsonを作成。Keypairを入力
Solflare Walletだとコード無しでkeypairを表示できるから便利











```価格を予測する為に時系列データを取得.
npx ts-node 001-download-candle-sticks-data.ts
```


HELLO_MOON_APIのレスポンスが変わってるみたいで動かなかった
002-train.tsを変更
```002-train.ts
import candleDataRaw from "./candleSticks.json";
import * as tf from "@tensorflow/tfjs-node";
import { TRAIN_TICKS_WINDOW, targetToken } from "./000-config";

interface Ohlc {
  mint: string;
  granularity: string;
  lastblockid: number;
  startTime: number;
  high: number;
  low: number;
  open: number;
  close: number;
  volume: number;
}

function parseCandleData(data: any): Ohlc[] {
  return data.map((item: any) => ({
    mint: item.mint,
    granularity: item.granularity,
    lastblockid: item.lastblockid,
    startTime: item.startTime,
    high: parseFloat(item.high),
    low: parseFloat(item.low),
    open: parseFloat(item.open),
    close: parseFloat(item.close),
    volume: parseFloat(item.volume),
  }));
}

const candleData: Ohlc[] = parseCandleData(candleDataRaw);

async function trainModel(
  trainX: number[][],
  trainY: number[]
): Promise<tf.LayersModel> {
  const tensorX = tf.tensor2d(trainX);
  const tensorY = tf.tensor1d(trainY);
  const model = tf.sequential();
  model.add(
    tf.layers.dense({
      inputShape: [tensorX.shape[1]],
      units: 64,
      activation: "relu",
    })
  );
  model.add(tf.layers.dense({ units: 32, activation: "relu" }));
  model.add(tf.layers.dense({ units: 1 }));
  model.compile({
    optimizer: tf.train.adam(),
    loss: tf.losses.meanSquaredError,
  });
  await model.fit(tensorX, tensorY, {
    batchSize: 32,
    epochs: 500,
    shuffle: true,
    verbose: 1,
  });
  return model;
}

function preprocessData(candleData: Ohlc[]): {
  trainX: number[][];
  trainY: number[];
} {
  const trainX: number[][] = [];
  const trainY: number[] = [];
  const volatilities = candleData.map(
    (candle) =>
      (Number(candle.high) - Number(candle.low)) / Math.pow(10, targetToken.decimals)
  );
  const windowSize = TRAIN_TICKS_WINDOW;
  for (let i = 0; i < candleData.length - windowSize - 1; i++) {
    const window = volatilities.slice(i, i + windowSize);
    const next = volatilities[i + windowSize];
    trainX.push(window);
    trainY.push(next);
  }
  return { trainX, trainY };
}

async function main() {
  const { trainX, trainY } = preprocessData(candleData);
  console.log("Training model...");
  const model = await trainModel(trainX, trainY);
  console.log("Model trained.");
  await model.save("file://./model");
}

main();
```






```価格予測モデルを作成.
npx ts-node 002-train.ts
```
![スクリーンショット 2024-04-26 051622.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/a340f7b8-f8ba-9c39-0ac1-a47c2fc363e7.png)
プログラムすたーと！
```
npm run start
```

![スクリーンショット 2024-04-26 063708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/466417c6-1693-0191-d490-7b484129d9a1.png)

依存関係の知識がなくてChatGPT4とあれこれしました
claude（無料版）の方が依存関係に良い答えを出してくれた（印象
とても面白いプログラムだと思い、今回取り上げさせて頂きました。
多種多様な戦略が出来そうだし、機械学習の予測モデルも個性が出そう。

@regonn_haizine様公開ありがとうございます

![スクリーンショット 2024-04-26 065726.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573208/2d569e64-04c4-61a5-b3e7-57682d8fabab.png)